Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ private List<List<String>> getPrimaryStorageCombinationFromSpec(VmInstanceSpec s
} else {
dataPs.add(null);
}
filterPrimaryStorageCandidates(spec, rootPs, autoAllocateRootVolumePs);

List<List<String>> finalPsCombos = new ArrayList<>();
if (autoAllocateRootVolumePs && autoAllocateDataVolumePs) {
Expand All @@ -478,6 +479,13 @@ private List<List<String>> getPrimaryStorageCombinationFromSpec(VmInstanceSpec s
return finalPsCombos;
}

private void filterPrimaryStorageCandidates(VmInstanceSpec spec, List<String> rootPs, boolean rootAutoAllocation) {
for (VmAllocatePrimaryStorageExtensionPoint ext :
pluginRgty.getExtensionList(VmAllocatePrimaryStorageExtensionPoint.class)) {
ext.filterPrimaryStorageCandidates(spec, rootPs, rootAutoAllocation);
}
}

private void sortPrimaryStorages(final List<String> psUuids, String strategy, VmInstanceSpec.ImageSpec imageSpec) {
List<PrimaryStorageVO> primaryStorageVOS = psUuids.stream().map(uuid -> dbf.findByUuid(uuid, PrimaryStorageVO.class)).collect(Collectors.toList());
for (PrimaryStorageSortExtensionPoint ext : pluginRgty.getExtensionList(PrimaryStorageSortExtensionPoint.class)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.zstack.header.storage.primary.AllocatePrimaryStorageSpaceReply;
import org.zstack.header.storage.primary.PrimaryStorageAllocationPurpose;
import org.zstack.header.storage.primary.PrimaryStorageConstant;
import org.zstack.header.storage.primary.PrimaryStorageFeature;
import org.zstack.header.storage.primary.ReleasePrimaryStorageSpaceMsg;
import org.zstack.header.vm.DiskAO;
import org.zstack.header.vm.VmInstanceConstant;
Expand Down Expand Up @@ -147,6 +148,10 @@ private AllocatePrimaryStorageSpaceMsg buildMessageForRootVolume(final VmInstanc
rmsg.setCandidatePrimaryStorageUuids(candidatePs);
rmsg.setPossiblePrimaryStorageTypes(selectPsTypesFromSpec(spec));
}
if (disk != null && Boolean.TRUE.equals(disk.getEncrypted())
&& disk.getPrimaryStorageUuid() == null && isEmpty(candidatePs)) {
rmsg.addRequiredFeature(PrimaryStorageFeature.ENCRYPTED_VOLUME);
}

Set<String> tags = new HashSet<>();
if (disk != null && disk.getSystemTags() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public void run(final FlowTrigger chain, final Map data) {
} else {
amsg.setRequiredHostUuid(hinv.getUuid());
}
if (Boolean.TRUE.equals(volume.getEncrypted())) {
amsg.addRequiredFeature(PrimaryStorageFeature.ENCRYPTED_VOLUME);
}

bus.send(amsg, new CloudBusCallBack(chain) {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ public void run(final FlowTrigger innerTrigger, Map data) {
amsg.setRequiredPrimaryStorageUuid(diskAO.getPrimaryStorageUuid());
amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString());
amsg.setTags(diskAO.getSystemTags());
if (Boolean.TRUE.equals(diskAO.getEncrypted()) && diskAO.getPrimaryStorageUuid() == null) {
amsg.addRequiredFeature(PrimaryStorageFeature.ENCRYPTED_VOLUME);
}
bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID);
bus.send(amsg, new CloudBusCallBack(innerTrigger) {
@Override
Expand Down Expand Up @@ -280,6 +283,9 @@ public void run(final FlowTrigger innerTrigger, Map data) {
List<String> bsUuids = template.getBackupStorageRefs().stream()
.map(ImageBackupStorageRefVO::getBackupStorageUuid).collect(Collectors.toList());
amsg.setPossiblePrimaryStorageTypes(possiblePrimaryStorageTypes(bsUuids));
if (Boolean.TRUE.equals(diskAO.getEncrypted())) {
amsg.addRequiredFeature(PrimaryStorageFeature.ENCRYPTED_VOLUME);
}

bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID);
bus.send(amsg, new CloudBusCallBack(innerTrigger) {
Expand Down
8 changes: 8 additions & 0 deletions conf/springConfigXml/VolumeManager.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@
</zstack:plugin>
</bean>

<bean id="EncryptedVolumePrimaryStorageAllocatorExtension"
class="org.zstack.storage.encrypt.EncryptedVolumePrimaryStorageAllocatorExtension">
<zstack:plugin>
<zstack:extension interface="org.zstack.header.vm.VmAllocatePrimaryStorageExtensionPoint"/>
<zstack:extension interface="org.zstack.storage.primary.PrimaryStorageFeatureAllocatorExtensionPoint"/>
</zstack:plugin>
</bean>

<bean id="VolumeEncryptedStartExtension" class="org.zstack.storage.encrypt.VolumeEncryptedStartExtension">
<zstack:plugin>
<zstack:extension interface="org.zstack.header.vm.VmBeforeStartOnHypervisorExtensionPoint"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

Expand Down Expand Up @@ -55,6 +56,13 @@ public void setRequiredFeatures(Set<PrimaryStorageFeature> requiredFeatures) {
this.requiredFeatures = requiredFeatures;
}

public void addRequiredFeature(PrimaryStorageFeature requiredFeature) {
requiredFeatures = requiredFeatures == null || requiredFeatures.isEmpty()
? EnumSet.of(requiredFeature)
: EnumSet.copyOf(requiredFeatures);
requiredFeatures.add(requiredFeature);
}

public List<String> getExcludePrimaryStorageTypes() {
return excludePrimaryStorageTypes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
*/
public enum PrimaryStorageFeature {
SHARED_VOLUME,
ENCRYPTED_VOLUME,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.zstack.header.vm;

import java.util.List;

public interface VmAllocatePrimaryStorageExtensionPoint {
void filterPrimaryStorageCandidates(VmInstanceSpec spec, List<String> rootPrimaryStorageUuids,
boolean rootPrimaryStorageAutoAllocation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ public void run(final FlowTrigger trigger, final Map data) {
if (localStorageHostRefVOList != null && !localStorageHostRefVOList.isEmpty()) {
localStorageHostRefVOList.forEach(r -> amsg.addExcludePrimaryStorageUuid(r.getPrimaryStorageUuid()));
}
if (Boolean.TRUE.equals(volume.getEncrypted())) {
amsg.addRequiredFeature(PrimaryStorageFeature.ENCRYPTED_VOLUME);
}
} else {
amsg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY);
amsg.setRequiredPrimaryStorageUuid(spec.getVmInventory().getRootVolume().getPrimaryStorageUuid());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.zstack.storage.encrypt;

import org.zstack.core.db.Q;
import org.zstack.header.storage.addon.primary.ExternalPrimaryStorageVO;
import org.zstack.header.storage.addon.primary.ExternalPrimaryStorageVO_;
import org.zstack.header.storage.primary.PrimaryStorageFeature;
import org.zstack.header.storage.primary.PrimaryStorageVO;
import org.zstack.header.vm.VmAllocatePrimaryStorageExtensionPoint;
import org.zstack.header.vm.VmInstanceSpec;
import org.zstack.header.volume.VolumeProtocol;
import org.zstack.storage.primary.PrimaryStorageFeatureAllocatorExtensionPoint;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class EncryptedVolumePrimaryStorageAllocatorExtension implements VmAllocatePrimaryStorageExtensionPoint,
PrimaryStorageFeatureAllocatorExtensionPoint {
private static final String ZHPS_PRIMARY_STORAGE_IDENTITY = "expon";
private static final String ZHPS_PRIMARY_STORAGE_PROTOCOL = VolumeProtocol.Vhost.name();

@Override
public List<PrimaryStorageVO> allocatePrimaryStorage(Set<PrimaryStorageFeature> requiredFeatures,
List<PrimaryStorageVO> candidates) {
if (!requiredFeatures.contains(PrimaryStorageFeature.ENCRYPTED_VOLUME) || candidates.isEmpty()) {
return candidates;
}

List<String> psUuids = candidates.stream().map(PrimaryStorageVO::getUuid).collect(Collectors.toList());
Set<String> unsupportedPsUuids = new HashSet<>(getEncryptedVolumeUnsupportedPrimaryStorageUuids(psUuids));
candidates.removeIf(ps -> unsupportedPsUuids.contains(ps.getUuid()));
return candidates;
}

@Override
public void filterPrimaryStorageCandidates(VmInstanceSpec spec, List<String> rootPrimaryStorageUuids,
boolean rootPrimaryStorageAutoAllocation) {
if (!rootPrimaryStorageAutoAllocation || spec.getRootDisk() == null
|| !Boolean.TRUE.equals(spec.getRootDisk().getEncrypted()) || rootPrimaryStorageUuids.isEmpty()) {
return;
}

Set<String> unsupportedPsUuids = new HashSet<>(
getEncryptedVolumeUnsupportedPrimaryStorageUuids(rootPrimaryStorageUuids));
rootPrimaryStorageUuids.removeIf(unsupportedPsUuids::contains);
}

public boolean isEncryptedVolumeUnsupportedPrimaryStorage(String psUuid) {
return psUuid != null && !getEncryptedVolumeUnsupportedPrimaryStorageUuids(
Collections.singletonList(psUuid)).isEmpty();
}

private List<String> getEncryptedVolumeUnsupportedPrimaryStorageUuids(List<String> psUuids) {
return Q.New(ExternalPrimaryStorageVO.class)
.select(ExternalPrimaryStorageVO_.uuid)
.eq(ExternalPrimaryStorageVO_.identity, ZHPS_PRIMARY_STORAGE_IDENTITY)
.eq(ExternalPrimaryStorageVO_.defaultProtocol, ZHPS_PRIMARY_STORAGE_PROTOCOL)
.in(ExternalPrimaryStorageVO_.uuid, psUuids)
.listValues();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.zstack.header.vm.VmInstanceSpec.ImageSpec;
import org.zstack.header.volume.*;
import org.zstack.identity.AccountManager;
import org.zstack.storage.encrypt.EncryptedVolumePrimaryStorageAllocatorExtension;
import org.zstack.utils.Utils;
import org.zstack.utils.gson.JSONObjectUtil;
import org.zstack.utils.logging.CLogger;
Expand All @@ -31,6 +32,8 @@
import java.net.URISyntaxException;
import java.util.*;

import static org.zstack.core.Platform.operr;

public class InstantiateVolumeForNewCreatedVmExtension implements PreVmInstantiateResourceExtensionPoint {
private static final CLogger logger = Utils.getLogger(InstantiateVolumeForNewCreatedVmExtension.class);

Expand All @@ -42,6 +45,8 @@ public class InstantiateVolumeForNewCreatedVmExtension implements PreVmInstantia
private PluginRegistry pluginRgty;
@Autowired
protected AccountManager acntMgr;
@Autowired
private EncryptedVolumePrimaryStorageAllocatorExtension encryptedVolumePrimaryStorageAllocatorExtension;

@Override
public void preBeforeInstantiateVmResource(VmInstanceSpec spec) throws VmInstantiateResourceException {
Expand Down Expand Up @@ -246,6 +251,12 @@ public void preInstantiateVmResource(VmInstanceSpec spec, Completion completion)

for (DiskAO diskAO : templateDataDisks) {
String psUuid = diskAO.getPrimaryStorageUuid() != null ? diskAO.getPrimaryStorageUuid() : defaultPsUuid;
if (diskAO.getPrimaryStorageUuid() == null && Boolean.TRUE.equals(diskAO.getEncrypted())
&& encryptedVolumePrimaryStorageAllocatorExtension
.isEncryptedVolumeUnsupportedPrimaryStorage(psUuid)) {
completion.fail(operr("no primary storage candidate is available"));
return;
}
msgs.add(buildCreateDataVolumeFromTemplateMsg(spec, diskAO.getTemplateUuid(), psUuid,
diskAO.getSystemTags(), accountUuid, diskAO.getEncrypted()));
}
Expand Down
Loading