use of com.cloud.agent.api.to.StorageFilerTO in project cloudstack by apache.
the class CitrixDeleteStoragePoolCommandWrapper method execute.
@Override
public Answer execute(final DeleteStoragePoolCommand command, final CitrixResourceBase citrixResourceBase) {
final Connection conn = citrixResourceBase.getConnection();
final StorageFilerTO poolTO = command.getPool();
try {
final SR sr;
// instead of pulling it out using getUuid of the StorageFilerTO instance.
if (command.getRemoveDatastore()) {
Map<String, String> details = command.getDetails();
String srNameLabel = details.get(DeleteStoragePoolCommand.DATASTORE_NAME);
sr = citrixResourceBase.getStorageRepository(conn, srNameLabel);
} else {
sr = citrixResourceBase.getStorageRepository(conn, poolTO.getUuid());
}
citrixResourceBase.removeSR(conn, sr);
final Answer answer = new Answer(command, true, "success");
return answer;
} catch (final Exception e) {
final String msg = "DeleteStoragePoolCommand XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + poolTO.getHost() + poolTO.getPath();
s_logger.error(msg, e);
return new Answer(command, false, msg);
}
}
use of com.cloud.agent.api.to.StorageFilerTO in project cloudstack by apache.
the class LibvirtResizeVolumeCommandWrapper method execute.
@Override
public Answer execute(final ResizeVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
final String volid = command.getPath();
final long newSize = command.getNewSize();
final long currentSize = command.getCurrentSize();
final String vmInstanceName = command.getInstanceName();
final boolean shrinkOk = command.getShrinkOk();
final StorageFilerTO spool = command.getPool();
final String notifyOnlyType = "NOTIFYONLY";
if (currentSize == newSize) {
// nothing to do
s_logger.info("No need to resize volume: current size " + currentSize + " is same as new size " + newSize);
return new ResizeVolumeAnswer(command, true, "success", currentSize);
}
try {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
KVMStoragePool pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
final KVMPhysicalDisk vol = pool.getPhysicalDisk(volid);
final String path = vol.getPath();
String type = notifyOnlyType;
if (pool.getType() != StoragePoolType.RBD) {
type = libvirtComputingResource.getResizeScriptType(pool, vol);
if (type.equals("QCOW2") && shrinkOk) {
return new ResizeVolumeAnswer(command, false, "Unable to shrink volumes of type " + type);
}
} else {
s_logger.debug("Volume " + path + " is on a RBD storage pool. No need to query for additional information.");
}
s_logger.debug("Resizing volume: " + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk);
/* libvirt doesn't support resizing (C)LVM devices, and corrupts QCOW2 in some scenarios, so we have to do these via Bash script */
if (pool.getType() != StoragePoolType.CLVM && vol.getFormat() != PhysicalDiskFormat.QCOW2) {
s_logger.debug("Volume " + path + " can be resized by libvirt. Asking libvirt to resize the volume.");
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
final Connect conn = libvirtUtilitiesHelper.getConnection();
final StorageVol v = conn.storageVolLookupByPath(path);
int flags = 0;
if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW && pool.getType() != StoragePoolType.RBD) {
flags = 1;
}
if (shrinkOk) {
flags = 4;
}
v.resize(newSize, flags);
} catch (final LibvirtException e) {
return new ResizeVolumeAnswer(command, false, e.toString());
}
}
s_logger.debug("Invoking resize script to handle type " + type);
final Script resizecmd = new Script(libvirtComputingResource.getResizeVolumePath(), libvirtComputingResource.getCmdsTimeout(), s_logger);
resizecmd.add("-s", String.valueOf(newSize));
resizecmd.add("-c", String.valueOf(currentSize));
resizecmd.add("-p", path);
resizecmd.add("-t", type);
resizecmd.add("-r", String.valueOf(shrinkOk));
resizecmd.add("-v", vmInstanceName);
final String result = resizecmd.execute();
if (result != null) {
if (type.equals(notifyOnlyType)) {
return new ResizeVolumeAnswer(command, true, "Resize succeeded, but need reboot to notify guest");
} else {
return new ResizeVolumeAnswer(command, false, result);
}
}
/* fetch new size as seen from libvirt, don't want to assume anything */
pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
pool.refresh();
final long finalSize = pool.getPhysicalDisk(volid).getVirtualSize();
s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize);
return new ResizeVolumeAnswer(command, true, "success", finalSize);
} catch (final CloudRuntimeException e) {
final String error = "Failed to resize volume: " + e.getMessage();
s_logger.debug(error);
return new ResizeVolumeAnswer(command, false, error);
}
}
use of com.cloud.agent.api.to.StorageFilerTO in project cloudstack by apache.
the class VmwareResource method execute.
protected Answer execute(MigrateWithStorageCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource MigrateWithStorageCommand: " + _gson.toJson(cmd));
}
VirtualMachineTO vmTo = cmd.getVirtualMachine();
String vmName = vmTo.getName();
VmwareHypervisorHost srcHyperHost = null;
VmwareHypervisorHost tgtHyperHost = null;
VirtualMachineMO vmMo = null;
ManagedObjectReference morDsAtTarget = null;
ManagedObjectReference morDsAtSource = null;
ManagedObjectReference morDc = null;
ManagedObjectReference morDcOfTargetHost = null;
ManagedObjectReference morTgtHost = new ManagedObjectReference();
ManagedObjectReference morTgtDatastore = new ManagedObjectReference();
VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
VirtualMachineRelocateSpecDiskLocator diskLocator = null;
String tgtDsName = "";
String tgtDsHost;
String tgtDsPath;
int tgtDsPort;
VolumeTO volume;
StorageFilerTO filerTo;
Set<String> mountedDatastoresAtSource = new HashSet<String>();
List<VolumeObjectTO> volumeToList = new ArrayList<VolumeObjectTO>();
Map<Long, Integer> volumeDeviceKey = new HashMap<Long, Integer>();
List<Pair<VolumeTO, StorageFilerTO>> volToFiler = cmd.getVolumeToFilerAsList();
String tgtHost = cmd.getTargetHost();
String tgtHostMorInfo = tgtHost.split("@")[0];
morTgtHost.setType(tgtHostMorInfo.split(":")[0]);
morTgtHost.setValue(tgtHostMorInfo.split(":")[1]);
try {
srcHyperHost = getHyperHost(getServiceContext());
tgtHyperHost = new HostMO(getServiceContext(), morTgtHost);
morDc = srcHyperHost.getHyperHostDatacenter();
morDcOfTargetHost = tgtHyperHost.getHyperHostDatacenter();
if (!morDc.getValue().equalsIgnoreCase(morDcOfTargetHost.getValue())) {
String msg = "Source host & target host are in different datacentesr";
throw new CloudRuntimeException(msg);
}
VmwareManager mgr = tgtHyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
String srcHostApiVersion = ((HostMO) srcHyperHost).getHostAboutInfo().getApiVersion();
// find VM through datacenter (VM is not at the target host yet)
vmMo = srcHyperHost.findVmOnPeerHyperHost(vmName);
if (vmMo == null) {
String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
s_logger.error(msg);
throw new Exception(msg);
}
vmName = vmMo.getName();
// Specify destination datastore location for each volume
for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
volume = entry.first();
filerTo = entry.second();
s_logger.debug("Preparing spec for volume : " + volume.getName());
morDsAtTarget = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, filerTo.getUuid());
morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, filerTo.getUuid());
if (morDsAtTarget == null) {
String msg = "Unable to find the target datastore: " + filerTo.getUuid() + " on target host: " + tgtHyperHost.getHyperHostName() + " to execute MigrateWithStorageCommand";
s_logger.error(msg);
throw new Exception(msg);
}
morTgtDatastore = morDsAtTarget;
// So since only the datastore will be changed first, ensure the target datastore is mounted on source host.
if (srcHostApiVersion.compareTo("5.1") < 0) {
tgtDsName = filerTo.getUuid().replace("-", "");
tgtDsHost = filerTo.getHost();
tgtDsPath = filerTo.getPath();
tgtDsPort = filerTo.getPort();
// If datastore is NFS and target datastore is not already mounted on source host then mount the datastore.
if (filerTo.getType().equals(StoragePoolType.NetworkFilesystem)) {
if (morDsAtSource == null) {
morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName);
if (morDsAtSource == null) {
throw new Exception("Unable to mount NFS datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
}
mountedDatastoresAtSource.add(tgtDsName);
s_logger.debug("Mounted datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
}
}
// If datastore is VMFS and target datastore is not mounted or accessible to source host then fail migration.
if (filerTo.getType().equals(StoragePoolType.VMFS)) {
if (morDsAtSource == null) {
s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to manually mounted on source host for a successful live storage migration.");
throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not mounted on source host: " + _hostName);
}
DatastoreMO dsAtSourceMo = new DatastoreMO(getServiceContext(), morDsAtSource);
String srcHostValue = srcHyperHost.getMor().getValue();
if (!dsAtSourceMo.isAccessibleToHost(srcHostValue)) {
s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to accessible to source host for a successful live storage migration.");
throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not accessible on source host: " + _hostName);
}
}
morTgtDatastore = morDsAtSource;
}
if (volume.getType() == Volume.Type.ROOT) {
relocateSpec.setDatastore(morTgtDatastore);
}
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDatastore(morDsAtSource);
Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, volume.getPath() + ".vmdk");
String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
}
int diskId = diskInfo.first().getKey();
diskLocator.setDiskId(diskId);
diskLocators.add(diskLocator);
volumeDeviceKey.put(volume.getId(), diskId);
}
// If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
// Hence set the existing datastore as target datastore for volumes that are not to be migrated.
List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
if (!volumeDeviceKey.containsValue(diskDatastore.first().intValue())) {
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDiskId(diskDatastore.first().intValue());
diskLocator.setDatastore(diskDatastore.second());
diskLocators.add(diskLocator);
}
}
relocateSpec.getDisk().addAll(diskLocators);
// Prepare network at target before migration
NicTO[] nics = vmTo.getNics();
for (NicTO nic : nics) {
// prepare network on the host
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), morTgtHost), nic, false, vmTo.getType());
}
// Ensure secondary storage mounted on target host
Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
String secStoreUrl = secStoreUrlAndId.first();
Long secStoreId = secStoreUrlAndId.second();
if (secStoreUrl == null) {
String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
throw new Exception(msg);
}
mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
if (morSecDs == null) {
String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
throw new Exception(msg);
}
if (srcHostApiVersion.compareTo("5.1") < 0) {
// Migrate VM's volumes to target datastore(s).
if (!vmMo.changeDatastore(relocateSpec)) {
throw new Exception("Change datastore operation failed during storage migration");
} else {
s_logger.debug("Successfully migrated storage of VM " + vmName + " to target datastore(s)");
}
// Migrate VM to target host.
ManagedObjectReference morPool = tgtHyperHost.getHyperHostOwnerResourcePool();
if (!vmMo.migrate(morPool, tgtHyperHost.getMor())) {
throw new Exception("VM migration to target host failed during storage migration");
} else {
s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName());
}
} else {
// Simultaneously migrate VM's volumes to target datastore and VM to target host.
relocateSpec.setHost(tgtHyperHost.getMor());
relocateSpec.setPool(tgtHyperHost.getHyperHostOwnerResourcePool());
if (!vmMo.changeDatastore(relocateSpec)) {
throw new Exception("Change datastore operation failed during storage migration");
} else {
s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName() + " and its storage to target datastore(s)");
}
}
// In case of a linked clone VM, if VM's disks are not consolidated, further VM operations such as volume snapshot, VM snapshot etc. will result in DB inconsistencies.
if (!vmMo.consolidateVmDisks()) {
s_logger.warn("VM disk consolidation failed after storage migration. Yet proceeding with VM migration.");
} else {
s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
}
// Update and return volume path and chain info for every disk because that could have changed after migration
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
volume = entry.first();
long volumeId = volume.getId();
VirtualDisk[] disks = vmMo.getAllDiskDevice();
for (VirtualDisk disk : disks) {
if (volumeDeviceKey.get(volumeId) == disk.getKey()) {
VolumeObjectTO newVol = new VolumeObjectTO();
String newPath = vmMo.getVmdkFileBaseName(disk);
String poolName = entry.second().getUuid().replace("-", "");
VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolName);
newVol.setId(volumeId);
newVol.setPath(newPath);
newVol.setChainInfo(_gson.toJson(diskInfo));
volumeToList.add(newVol);
break;
}
}
}
return new MigrateWithStorageAnswer(cmd, volumeToList);
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encountered remote exception at vCenter, invalidating VMware session context");
invalidateServiceContext();
}
String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
s_logger.warn(msg, e);
return new MigrateWithStorageAnswer(cmd, (Exception) e);
} finally {
// Cleanup datastores mounted on source host
for (String mountedDatastore : mountedDatastoresAtSource) {
s_logger.debug("Attempting to unmount datastore " + mountedDatastore + " at " + _hostName);
try {
srcHyperHost.unmountDatastore(mountedDatastore);
} catch (Exception unmountEx) {
s_logger.debug("Failed to unmount datastore " + mountedDatastore + " at " + _hostName + ". Seems the datastore is still being used by " + _hostName + ". Please unmount manually to cleanup.");
}
s_logger.debug("Successfully unmounted datastore " + mountedDatastore + " at " + _hostName);
}
}
}
use of com.cloud.agent.api.to.StorageFilerTO in project CloudStack-archive by CloudStack-extras.
the class MockStorageManagerImpl method ModifyStoragePool.
@Override
public ModifyStoragePoolAnswer ModifyStoragePool(ModifyStoragePoolCommand cmd) {
StorageFilerTO sf = cmd.getPool();
MockStoragePoolVO storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid());
if (storagePool == null) {
storagePool = new MockStoragePoolVO();
storagePool.setUuid(sf.getUuid());
storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator);
Long size = DEFAULT_HOST_STORAGE_SIZE;
String path = sf.getPath();
int index = path.lastIndexOf("/");
if (index != -1) {
path = path.substring(index + 1);
if (path != null) {
String[] values = path.split("=");
if (values.length > 1 && values[0].equalsIgnoreCase("size")) {
size = Long.parseLong(values[1]);
}
}
}
storagePool.setCapacity(size);
storagePool.setStorageType(sf.getType());
storagePool = _mockStoragePoolDao.persist(storagePool);
}
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
}
use of com.cloud.agent.api.to.StorageFilerTO in project CloudStack-archive by CloudStack-extras.
the class MockStorageManagerImpl method CreateStoragePool.
@Override
public Answer CreateStoragePool(CreateStoragePoolCommand cmd) {
StorageFilerTO sf = cmd.getPool();
MockStoragePoolVO storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid());
if (storagePool == null) {
storagePool = new MockStoragePoolVO();
storagePool.setUuid(sf.getUuid());
storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator);
Long size = DEFAULT_HOST_STORAGE_SIZE;
String path = sf.getPath();
int index = path.lastIndexOf("/");
if (index != -1) {
path = path.substring(index + 1);
if (path != null) {
String[] values = path.split("=");
if (values.length > 1 && values[0].equalsIgnoreCase("size")) {
size = Long.parseLong(values[1]);
}
}
}
storagePool.setCapacity(size);
storagePool.setStorageType(sf.getType());
storagePool = _mockStoragePoolDao.persist(storagePool);
}
return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap<String, TemplateInfo>());
}
Aggregations