use of com.linbit.linstor.api.model.ApiCallRcList in project cloudstack by apache.
the class LinstorPrimaryDataStoreDriverImpl method takeSnapshot.
@Override
public void takeSnapshot(SnapshotInfo snapshotInfo, AsyncCompletionCallback<CreateCmdResult> callback) {
s_logger.debug("Linstor: takeSnapshot with snapshot: " + snapshotInfo.getUuid());
final VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
final VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId());
long storagePoolId = volumeVO.getPoolId();
final StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
final DevelopersApi api = LinstorUtil.getLinstorAPI(storagePool.getHostAddress());
final String rscName = LinstorUtil.RSC_PREFIX + volumeVO.getPath();
Snapshot snapshot = new Snapshot();
snapshot.setName(getSnapshotName(snapshotInfo.getUuid()));
CreateCmdResult result;
try {
ApiCallRcList answers = api.resourceSnapshotCreate(rscName, snapshot);
if (answers.hasError()) {
final String errMsg = answers.get(0).getMessage();
s_logger.error("Snapshot error: " + errMsg);
result = new CreateCmdResult(null, new Answer(null, false, errMsg));
result.setResult(errMsg);
} else {
s_logger.info(String.format("Successfully took snapshot from %s", rscName));
SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO) snapshotInfo.getTO();
snapshotObjectTo.setPath(rscName + "-" + snapshotInfo.getName());
result = new CreateCmdResult(null, new CreateObjectAnswer(snapshotObjectTo));
result.setResult(null);
}
} catch (ApiException apiExc) {
s_logger.error(apiExc);
result = new CreateCmdResult(null, new Answer(null, false, apiExc.getBestMessage()));
result.setResult(apiExc.getBestMessage());
}
callback.complete(result);
}
use of com.linbit.linstor.api.model.ApiCallRcList in project cloudstack by apache.
the class LinstorPrimaryDataStoreDriverImpl method deleteSnapshot.
private void deleteSnapshot(@Nonnull DataStore dataStore, @Nonnull String rscDefName, @Nonnull String snapshotName) {
StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePool.getHostAddress());
try {
ApiCallRcList answers = linstorApi.resourceSnapshotDelete(rscDefName, snapshotName);
if (answers.hasError()) {
for (ApiCallRc answer : answers) {
s_logger.error(answer.getMessage());
}
throw new CloudRuntimeException("Linstor: Unable to delete snapshot: " + rscDefName);
}
} catch (ApiException apiEx) {
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
}
use of com.linbit.linstor.api.model.ApiCallRcList in project cloudstack by apache.
the class LinstorPrimaryDataStoreDriverImpl method createResource.
private String createResource(VolumeInfo vol, StoragePoolVO storagePoolVO) {
DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
final String rscGrp = storagePoolVO.getUserInfo() != null && !storagePoolVO.getUserInfo().isEmpty() ? storagePoolVO.getUserInfo() : "DfltRscGrp";
ResourceGroupSpawn rscGrpSpawn = new ResourceGroupSpawn();
final String rscName = LinstorUtil.RSC_PREFIX + vol.getUuid();
rscGrpSpawn.setResourceDefinitionName(rscName);
rscGrpSpawn.addVolumeSizesItem(vol.getSize() / 1024);
try {
s_logger.debug("Linstor: Spawn resource " + rscName);
ApiCallRcList answers = linstorApi.resourceGroupSpawn(rscGrp, rscGrpSpawn);
checkLinstorAnswersThrow(answers);
return getDeviceName(linstorApi, rscName);
} catch (ApiException apiEx) {
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
}
use of com.linbit.linstor.api.model.ApiCallRcList in project cloudstack by apache.
the class LinstorStorageAdaptor method createPhysicalDisk.
@Override
public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, QemuImg.PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
final String rscName = getLinstorRscName(name);
LinstorStoragePool lpool = (LinstorStoragePool) pool;
final DevelopersApi api = getLinstorAPI(pool);
try {
List<ResourceDefinition> definitionList = api.resourceDefinitionList(Collections.singletonList(rscName), null, null, null);
if (definitionList.isEmpty()) {
ResourceGroupSpawn rgSpawn = new ResourceGroupSpawn();
rgSpawn.setResourceDefinitionName(rscName);
// linstor uses KiB
rgSpawn.addVolumeSizesItem(size / 1024);
s_logger.debug("Linstor: Spawn resource " + rscName);
ApiCallRcList answers = api.resourceGroupSpawn(lpool.getResourceGroup(), rgSpawn);
handleLinstorApiAnswers(answers, "Linstor: Unable to spawn resource.");
}
// query linstor for the device path
List<ResourceWithVolumes> resources = api.viewResources(Collections.emptyList(), Collections.singletonList(rscName), Collections.emptyList(), null, null, null);
if (!resources.isEmpty() && !resources.get(0).getVolumes().isEmpty()) {
final String devPath = resources.get(0).getVolumes().get(0).getDevicePath();
s_logger.info("Linstor: Created drbd device: " + devPath);
final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devPath, name, pool);
kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
return kvmDisk;
} else {
s_logger.error("Linstor: viewResources didn't return resources or volumes.");
throw new CloudRuntimeException("Linstor: viewResources didn't return resources or volumes.");
}
} catch (ApiException apiEx) {
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
}
use of com.linbit.linstor.api.model.ApiCallRcList in project cloudstack by apache.
the class LinstorStorageAdaptor method disconnectPhysicalDiskByPath.
/**
* disconnectPhysicalDiskByPath is called after e.g. a live migration.
* The problem is we have no idea just from the path to which linstor-controller
* this resource would belong to. But as it should be highly unlikely that someone
* uses more than one linstor-controller to manage resource on the same kvm host.
* We will just take the first stored storagepool.
*/
@Override
public boolean disconnectPhysicalDiskByPath(String localPath) {
// get first storage pool from the map, as we don't know any better:
if (!MapStorageUuidToStoragePool.isEmpty()) {
s_logger.debug("Linstor: disconnectPhysicalDiskByPath " + localPath);
String firstKey = MapStorageUuidToStoragePool.keySet().stream().findFirst().get();
final KVMStoragePool pool = MapStorageUuidToStoragePool.get(firstKey);
s_logger.debug("Linstor: Using storpool: " + pool.getUuid());
final DevelopersApi api = getLinstorAPI(pool);
try {
List<ResourceWithVolumes> resources = api.viewResources(Collections.singletonList(localNodeName), null, null, null, null, null);
Optional<ResourceWithVolumes> rsc = getResourceByPath(resources, localPath);
if (rsc.isPresent()) {
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
ApiCallRcList answers = api.resourceDefinitionModify(rsc.get().getName(), rdm);
if (answers.hasError()) {
s_logger.error("Failed to remove 'allow-two-primaries' on " + rsc.get().getName());
throw new CloudRuntimeException(answers.get(0).getMessage());
}
return true;
}
s_logger.warn("Linstor: Couldn't find resource for this path: " + localPath);
} catch (ApiException apiEx) {
s_logger.error(apiEx);
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
}
return false;
}
Aggregations