Skip to content

Commit

Permalink
linstor: create template cache image before host copy
Browse files Browse the repository at this point in the history
Create the template image resource before the host gets the copy command.
This allowes to tag(set property) in linstor to which template this
resource belongs to and we can maybe in future reduce the linstor
managing code in the storagepoolAdaptor class.
  • Loading branch information
rp- committed Oct 13, 2023
1 parent 18cb11e commit 2b809cb
Showing 1 changed file with 80 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ResizeVolumePayload;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStoragePoolVO;
Expand Down Expand Up @@ -420,27 +421,46 @@ private void applyAuxProps(DevelopersApi api, String rscName, String dispName, S
}
}

private String createResource(VolumeInfo vol, StoragePoolVO storagePoolVO)
{
DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
final String rscGrp = storagePoolVO.getUserInfo() != null && !storagePoolVO.getUserInfo().isEmpty() ?
private String getRscGrp(StoragePoolVO storagePoolVO) {
return storagePoolVO.getUserInfo() != null && !storagePoolVO.getUserInfo().isEmpty() ?
storagePoolVO.getUserInfo() : "DfltRscGrp";
}

private String createResourceBase(
String rscName, long sizeInBytes, String volName, String vmName, DevelopersApi api, String rscGrp) {
ResourceGroupSpawn rscGrpSpawn = new ResourceGroupSpawn();
final String rscName = LinstorUtil.RSC_PREFIX + vol.getUuid();
rscGrpSpawn.setResourceDefinitionName(rscName);
rscGrpSpawn.addVolumeSizesItem(vol.getSize() / 1024);
rscGrpSpawn.addVolumeSizesItem(sizeInBytes / 1024);

try
{
s_logger.info("Linstor: Spawn resource " + rscName);
ApiCallRcList answers = linstorApi.resourceGroupSpawn(rscGrp, rscGrpSpawn);
ApiCallRcList answers = api.resourceGroupSpawn(rscGrp, rscGrpSpawn);
checkLinstorAnswersThrow(answers);

applyAuxProps(linstorApi, rscName, vol.getName(), vol.getAttachedVmName());
applyAuxProps(api, rscName, volName, vmName);

return getDeviceName(api, rscName);
} catch (ApiException apiEx)
{
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
}

private String createResource(VolumeInfo vol, StoragePoolVO storagePoolVO) {
DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
final String rscGrp = getRscGrp(storagePoolVO);

final String rscName = LinstorUtil.RSC_PREFIX + vol.getUuid();
String deviceName = createResourceBase(
rscName, vol.getSize(), vol.getName(), vol.getAttachedVmName(), linstorApi, rscGrp);

try
{
applyQoSSettings(storagePoolVO, linstorApi, rscName, vol.getMaxIops());

return getDeviceName(linstorApi, rscName);
return deviceName;
} catch (ApiException apiEx)
{
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
Expand Down Expand Up @@ -505,8 +525,7 @@ private String cloneResource(long csCloneId, VolumeInfo volumeInfo, StoragePoolV
}

private String createResourceFromSnapshot(long csSnapshotId, String rscName, StoragePoolVO storagePoolVO) {
final String rscGrp = storagePoolVO.getUserInfo() != null && !storagePoolVO.getUserInfo().isEmpty() ?
storagePoolVO.getUserInfo() : "DfltRscGrp";
final String rscGrp = getRscGrp(storagePoolVO);
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());

SnapshotVO snapshotVO = _snapshotDao.findById(csSnapshotId);
Expand Down Expand Up @@ -757,6 +776,13 @@ private static boolean canCopySnapshotCond(DataObject srcData, DataObject dstDat
|| dstData.getDataStore().getRole() == DataStoreRole.ImageCache);
}

private static boolean canCopyTemplateCond(DataObject srcData, DataObject dstData) {
return srcData.getType() == DataObjectType.TEMPLATE && dstData.getType() == DataObjectType.TEMPLATE
&& dstData.getDataStore().getRole() == DataStoreRole.Primary
&& (srcData.getDataStore().getRole() == DataStoreRole.Image
|| srcData.getDataStore().getRole() == DataStoreRole.ImageCache);
}

@Override
public boolean canCopy(DataObject srcData, DataObject dstData)
{
Expand All @@ -767,6 +793,9 @@ public boolean canCopy(DataObject srcData, DataObject dstData)
VolumeInfo volume = sinfo.getBaseVolume();
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
return storagePool.getStorageProviderName().equals(LinstorUtil.PROVIDER_NAME);
} else if (canCopyTemplateCond(srcData, dstData)) {
StoragePoolVO storagePoolVO = _storagePoolDao.findById(dstData.getDataStore().getId());
return storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.Linstor;
}
return false;
}
Expand Down Expand Up @@ -794,6 +823,9 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
}
res = new CopyCommandResult(null, answer);
res.setResult(errMsg);
} else if (canCopyTemplateCond(srcData, dstData)) {
Answer answer = copyTemplate(srcData, dstData);
res = new CopyCommandResult(null, answer);
} else {
Answer answer = new Answer(null, false, "noimpl");
res = new CopyCommandResult(null, answer);
Expand Down Expand Up @@ -821,6 +853,43 @@ private Optional<RemoteHostEndPoint> getDiskfullEP(DevelopersApi api, String rsc
return Optional.empty();
}

private Answer copyTemplate(DataObject srcData, DataObject dstData) {
TemplateInfo tInfo = (TemplateInfo) dstData;
final StoragePoolVO pool = _storagePoolDao.findById(dstData.getDataStore().getId());
final DevelopersApi api = LinstorUtil.getLinstorAPI(pool.getHostAddress());
final String rscName = LinstorUtil.RSC_PREFIX + dstData.getUuid();
createResourceBase(
LinstorUtil.RSC_PREFIX + dstData.getUuid(),
dstData.getSize(),
tInfo.getName(),
"",
api,
getRscGrp(pool));

int nMaxExecutionMinutes = NumbersUtil.parseInt(
_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
CopyCommand cmd = new CopyCommand(
srcData.getTO(),
dstData.getTO(),
nMaxExecutionMinutes * 60 * 1000,
VirtualMachineManager.ExecuteInSequence.value());
Answer answer;

try {
Optional<RemoteHostEndPoint> optEP = getDiskfullEP(api, rscName);
if (optEP.isPresent()) {
answer = optEP.get().sendMessage(cmd);
}
else {
answer = new Answer(cmd, false, "Unable to get matching Linstor endpoint.");
}
} catch (ApiException exc) {
s_logger.error("copy template failed: ", exc);
throw new CloudRuntimeException(exc.getBestMessage());
}
return answer;
}

protected Answer copySnapshot(DataObject srcData, DataObject destData) {
String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
int _backupsnapshotwait = NumbersUtil.parseInt(
Expand Down

0 comments on commit 2b809cb

Please sign in to comment.