Skip to content

Commit 930b4c6

Browse files
committed
changes for blank instance with security groups
Correct OS for worker VM is Rocky Linux 9 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 789764a commit 930b4c6

14 files changed

Lines changed: 184 additions & 83 deletions

File tree

api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ public boolean isCleanupExtraConfig() {
288288
return Boolean.TRUE.equals(cleanupExtraConfig);
289289
}
290290

291+
public void setId(Long id) {
292+
this.id = id;
293+
}
294+
295+
public void setSecurityGroupIdList(List<Long> securityGroupIdList) {
296+
this.securityGroupIdList = securityGroupIdList;
297+
}
298+
291299
/////////////////////////////////////////////////////
292300
/////////////// API Implementation///////////////////
293301
/////////////////////////////////////////////////////

engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ public interface SecurityGroupDao extends GenericDao<SecurityGroupVO, Long> {
3131
List<SecurityGroupVO> findByAccountAndNames(Long accountId, String... names);
3232

3333
int removeByAccountId(long accountId);
34+
35+
List<SecurityGroupVO> listByIds(List<Long> ids);
3436
}

engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDaoImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,14 @@ public boolean expunge(Long id) {
129129
txn.commit();
130130
return result;
131131
}
132+
133+
@Override
134+
public List<SecurityGroupVO> listByIds(List<Long> ids) {
135+
SearchBuilder<SecurityGroupVO> idsSearch = createSearchBuilder();
136+
idsSearch.and("ids", idsSearch.entity().getId(), SearchCriteria.Op.IN);
137+
idsSearch.done();
138+
SearchCriteria<SecurityGroupVO> sc = idsSearch.create();
139+
sc.setParameters("ids", ids.toArray());
140+
return listBy(sc);
141+
}
132142
}

engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
public interface NicDao extends GenericDao<NicVO, Long> {
2727
List<NicVO> listByVmId(long instanceId);
2828

29+
int countByVmId(long instanceId);
30+
2931
List<NicVO> listByVmIdOrderByDeviceId(long instanceId);
3032

3133
List<String> listIpAddressInNetwork(long networkConfigId);

engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ public List<NicVO> listByVmId(long instanceId) {
126126
return listBy(sc);
127127
}
128128

129+
@Override
130+
public int countByVmId(long instanceId) {
131+
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
132+
sc.setParameters("instance", instanceId);
133+
return getCount(sc);
134+
}
135+
129136
@Override
130137
public List<NicVO> listByVmIdOrderByDeviceId(long instanceId) {
131138
SearchCriteria<NicVO> sc = AllFieldsSearch.create();

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/adapter/ServerAdapter.java

Lines changed: 92 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
import java.util.Base64;
2424
import java.util.Collections;
2525
import java.util.HashMap;
26+
import java.util.HashSet;
2627
import java.util.List;
2728
import java.util.Map;
2829
import java.util.Objects;
30+
import java.util.Set;
2931
import java.util.UUID;
3032
import java.util.concurrent.TimeUnit;
3133
import java.util.stream.Collectors;
@@ -167,8 +169,10 @@
167169
import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
168170
import com.cloud.network.dao.NetworkDao;
169171
import com.cloud.network.dao.NetworkVO;
172+
import com.cloud.network.security.SecurityGroupVMMapVO;
170173
import com.cloud.network.security.SecurityGroupVO;
171174
import com.cloud.network.security.dao.SecurityGroupDao;
175+
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
172176
import com.cloud.offering.ServiceOffering;
173177
import com.cloud.org.Grouping;
174178
import com.cloud.projects.Project;
@@ -226,7 +230,7 @@ public class ServerAdapter extends ManagerBase {
226230
);
227231
private static final String VM_TAG_KEY = "veeam_tag";
228232
private static final String WORKER_VM_GUEST_CPU_MODE = "host-passthrough";
229-
private static final String WORKER_VM_GUEST_OS = "AlmaLinux 9";
233+
private static final String WORKER_VM_GUEST_OS = "Rocky Linux 9";
230234
private static final String RESTORE_CONFIG = "restore.config";
231235

232236
@Inject
@@ -343,6 +347,9 @@ public class ServerAdapter extends ManagerBase {
343347
@Inject
344348
SecurityGroupDao securityGroupDao;
345349

350+
@Inject
351+
SecurityGroupVMMapDao securityGroupVMMapDao;
352+
346353
@Inject
347354
SharedFSService sharedFSService;
348355

@@ -630,13 +637,39 @@ protected SecurityGroupVO getValidatedSecurityGroup(String securityGroupUuid) {
630637
}
631638
SecurityGroupVO group = securityGroupDao.findByUuid(securityGroupUuid);
632639
if (group == null) {
633-
logger.warn("Failed to find userdata with ID {} specified in Instance creation request, " +
634-
"skipping security group assignment", securityGroupUuid);
640+
logger.warn("Failed to find security group with ID {} specified in Instance creation request, " +
641+
"skipping its assignment", securityGroupUuid);
635642
return null;
636643
}
637644
return group;
638645
}
639646

647+
protected List<Long> getValidatedSecurityGroups(List<String> uuids, long vmId) {
648+
if (CollectionUtils.isEmpty(uuids)) {
649+
return null;
650+
}
651+
List<SecurityGroupVO> instanceGroups = getSecurityGroupsForInstance(vmId);
652+
Set<Long> existingIds = CollectionUtils.isNotEmpty(instanceGroups)
653+
? instanceGroups.stream().map(SecurityGroupVO::getId).collect(Collectors.toSet())
654+
: new HashSet<>();
655+
Set<Long> requestedIds = uuids.stream()
656+
.map(uuid -> {
657+
SecurityGroupVO group = getValidatedSecurityGroup(uuid);
658+
return group != null ? group.getId() : null;
659+
})
660+
.filter(Objects::nonNull)
661+
.collect(Collectors.toSet());
662+
if (CollectionUtils.isEmpty(requestedIds)) {
663+
return null;
664+
}
665+
Set<Long> mergedIds = new HashSet<>(existingIds);
666+
mergedIds.addAll(requestedIds);
667+
if (mergedIds.equals(existingIds)) {
668+
return null;
669+
}
670+
return new ArrayList<>(mergedIds);
671+
}
672+
640673
protected String getValidatedInstanceType(Vm request) {
641674
String instanceType = StringUtils.trimToNull(request.getInstanceType());
642675
if (StringUtils.isEmpty(request.getInstanceType())) {
@@ -667,7 +700,7 @@ protected Pair<Vm, UserVm> createInstance(com.cloud.dc.DataCenter zone, Long clu
667700
String accountName, Long projectId, String name, String displayName, String serviceOfferingUuid,
668701
int cpu, int memory, String templateUuid, GuestOS guestOs, String userdata, ApiConstants.BootType bootType,
669702
ApiConstants.BootMode bootMode, String affinityGroupId, String userDataId, String sshKeyPairNames,
670-
String instanceType, String securityGroupId, Map<String, String> details) {
703+
String instanceType, Map<String, String> details) {
671704
Account account = owner != null ? owner : CallContext.current().getCallingAccount();
672705
ServiceOffering serviceOffering = getServiceOfferingIdForVmCreation(zone, account, serviceOfferingUuid, cpu,
673706
memory);
@@ -714,10 +747,6 @@ protected Pair<Vm, UserVm> createInstance(com.cloud.dc.DataCenter zone, Long clu
714747
if (userData != null) {
715748
cmd.setUserDataId(userData.getId());
716749
}
717-
SecurityGroupVO securityGroup = getValidatedSecurityGroup(securityGroupId);
718-
if (securityGroup != null) {
719-
cmd.setSecurityGroupList(List.of(securityGroup.getId()));
720-
}
721750
if (StringUtils.isNotBlank(sshKeyPairNames)) {
722751
cmd.setSshKeyPairNames(getValidatedSshKeyPairNames(sshKeyPairNames, owner));
723752
}
@@ -736,7 +765,7 @@ protected Pair<Vm, UserVm> createInstance(com.cloud.dc.DataCenter zone, Long clu
736765
UserVmJoinVO vo = userVmJoinDao.findById(vm.getId());
737766
Vm vmObj = UserVmJoinVOToVmConverter.toVm(vo, this::getHostById, this::getDetailsByInstanceId,
738767
this::listTagsByInstanceId, this::listDiskAttachmentsByInstanceId, this::listNicsByInstance,
739-
null, false);
768+
null, null, false);
740769
return new Pair<>(vmObj, vm);
741770
} catch (InsufficientCapacityException | ResourceUnavailableException | ResourceAllocationException | CloudRuntimeException e) {
742771
throw new CloudRuntimeException("Failed to create VM: " + e.getMessage(), e);
@@ -823,12 +852,8 @@ protected void processInstanceRestoreConfigIfNeeded(UserVm userVm, Volume volume
823852
sharedFSService.updateSharedFSPostRestore(sharedFS.getId(), volume.getId());
824853
}
825854

826-
protected Pair<String, String> getValidatedInstanceNicDetails(final UserVmVO vm, final NetworkVO network) {
827-
if (ObjectUtils.anyNull(vm, network)) {
828-
return new Pair<>(null, null);
829-
}
830-
VMInstanceDetailVO detail = vmInstanceDetailsDao.findDetail(vm.getId(), RESTORE_CONFIG);
831-
if (detail == null || StringUtils.isBlank(detail.getValue())) {
855+
protected Pair<String, String> getValidatedInstanceNicDetails(final VMInstanceDetailVO detail, final NetworkVO network) {
856+
if (ObjectUtils.anyNull(detail, network) || StringUtils.isBlank(detail.getValue())) {
832857
return new Pair<>(null, null);
833858
}
834859
Pair<String, String> result = OvfXmlUtil.getVmNicDetailFromStoredConfig(detail.getValue(), network.getUuid(), logger);
@@ -862,6 +887,34 @@ protected Pair<String, String> getValidatedInstanceNicDetails(final UserVmVO vm,
862887
return new Pair<>(mac, ip4Address);
863888
}
864889

890+
protected void updateInstanceSecurityGroupsIfNeeded(final UserVmVO vmVo, final VMInstanceDetailVO detail, final NetworkVO network) {
891+
if (ObjectUtils.anyNull(detail, network) || StringUtils.isBlank(detail.getValue())) {
892+
return;
893+
}
894+
String config = detail.getValue();
895+
Vm vm = OvfXmlUtil.parseVmRestoreConfig(config, logger);
896+
if (CollectionUtils.isEmpty(vm.getSecurityGroupIds())) {
897+
return;
898+
}
899+
List<Long> securityGroupIds = getValidatedSecurityGroups(vm.getSecurityGroupIds(), vmVo.getId());
900+
if (CollectionUtils.isEmpty(securityGroupIds)) {
901+
return;
902+
}
903+
if (!networkModel.areServicesSupportedInNetwork(network.getId(), NetworkVO.Service.SecurityGroup)) {
904+
logger.debug("{} does not support security groups, will try with remaining networks for {}", network, vmVo);
905+
return;
906+
}
907+
UpdateVMCmd cmd = new UpdateVMCmd();
908+
ComponentContext.inject(cmd);
909+
cmd.setId(vmVo.getId());
910+
cmd.setSecurityGroupIdList(securityGroupIds);
911+
try {
912+
userVmManager.updateVirtualMachine(cmd);
913+
} catch (ResourceUnavailableException | InsufficientCapacityException e) {
914+
throw new CloudRuntimeException("Failed to add security group(s) due to: " + e.getMessage());
915+
}
916+
}
917+
865918
protected static long getProvisionedSizeInGb(String sizeStr) {
866919
long provisionedSizeInGb;
867920
try {
@@ -997,6 +1050,17 @@ protected SharedFS getSharedFSForInstance(UserVmJoinVO vo) {
9971050
return sharedFSService.getSharedFSForVmId(vo.getId());
9981051
}
9991052

1053+
protected List<SecurityGroupVO> getSecurityGroupsForInstance(long vmId) {
1054+
List<SecurityGroupVMMapVO> mappings = securityGroupVMMapDao.listByInstanceId(vmId);
1055+
if (CollectionUtils.isEmpty(mappings)) {
1056+
return null;
1057+
}
1058+
return securityGroupDao.listByIds(
1059+
mappings.stream()
1060+
.map(SecurityGroupVMMapVO::getSecurityGroupId)
1061+
.collect(Collectors.toList()));
1062+
}
1063+
10001064
protected void validateInstanceBackupConditions(UserVm vm) {
10011065
List<AutoScaleVmGroupVmMapVO> asGroupVmVOs = autoScaleVmGroupVmMapDao.listByVm(vm.getId());
10021066
if (CollectionUtils.isNotEmpty(asGroupVmVOs)) {
@@ -1138,10 +1202,11 @@ public List<Vm> listAllInstances(boolean includeTags, boolean includeDisks, bool
11381202
return UserVmJoinVOToVmConverter.toVmList(vms,
11391203
this::getHostById,
11401204
this::getDetailsByInstanceId,
1141-
includeTags ? this::listTagsByInstanceId : null,
1142-
includeDisks ? this::listDiskAttachmentsByInstanceId : null,
1143-
includeNics ? this::listNicsByInstance : null,
1205+
(includeTags || allContent) ? this::listTagsByInstanceId : null,
1206+
(includeDisks || allContent) ? this::listDiskAttachmentsByInstanceId : null,
1207+
(includeNics || allContent) ? this::listNicsByInstance : null,
11441208
allContent ? this::getSharedFSForInstance: null,
1209+
allContent ? this::getSecurityGroupsForInstance: null,
11451210
allContent);
11461211
}
11471212

@@ -1155,10 +1220,11 @@ public Vm getInstance(String uuid, boolean includeTags, boolean includeDisks, bo
11551220
return UserVmJoinVOToVmConverter.toVm(vo,
11561221
this::getHostById,
11571222
this::getDetailsByInstanceId,
1158-
includeTags ? this::listTagsByInstanceId : null,
1159-
includeDisks ? this::listDiskAttachmentsByInstanceId : null,
1160-
includeNics ? this::listNicsByInstance : null,
1161-
allContent ? this::getSharedFSForInstance : null,
1223+
(includeTags || allContent) ? this::listTagsByInstanceId : null,
1224+
(includeDisks || allContent) ? this::listDiskAttachmentsByInstanceId : null,
1225+
(includeNics || allContent) ? this::listNicsByInstance : null,
1226+
allContent ? this::getSharedFSForInstance: null,
1227+
allContent ? this::getSecurityGroupsForInstance: null,
11621228
allContent);
11631229
}
11641230

@@ -1227,8 +1293,7 @@ public Vm createInstance(Vm request) {
12271293
Pair<Vm, UserVm> result = createInstance(zone, clusterId, owner, ownerDetails.first(), ownerDetails.second(),
12281294
ownerDetails.third(), name, displayName, serviceOfferingUuid, cpu, memoryMB, templateUuid, guestOs,
12291295
userdata, bootOptions.first(), bootOptions.second(), request.getAffinityGroupId(),
1230-
request.getUserDataId(), request.getSshKeyPairNames(), instanceType,
1231-
request.getSecurityGroupId(), request.getDetails());
1296+
request.getUserDataId(), request.getSshKeyPairNames(), instanceType, request.getDetails());
12321297
saveInstanceRestoreConfig(request, result.second());
12331298
return result.first();
12341299
}
@@ -1583,7 +1648,8 @@ public Nic attachInstanceNic(final String vmUuid, final Nic request) {
15831648
accountCannotAccessNetwork(networkVO, vmVo.getAccountId())) {
15841649
assignVmToAccount(vmVo, networkVO.getAccountId());
15851650
}
1586-
Pair<String, String> nicDetails = getValidatedInstanceNicDetails(vmVo, networkVO);
1651+
VMInstanceDetailVO detail = vmInstanceDetailsDao.findDetail(vmVo.getId(), RESTORE_CONFIG);
1652+
Pair<String, String> nicDetails = getValidatedInstanceNicDetails(detail, networkVO);
15871653
AddNicToVMCmd cmd = new AddNicToVMCmd();
15881654
ComponentContext.inject(cmd);
15891655
cmd.setVmId(vmVo.getId());
@@ -1598,6 +1664,7 @@ public Nic attachInstanceNic(final String vmUuid, final Nic request) {
15981664
if (nic == null) {
15991665
throw new CloudRuntimeException("Failed to attach NIC to VM");
16001666
}
1667+
updateInstanceSecurityGroupsIfNeeded(vmVo, detail, networkVO);
16011668
return NicVOToNicConverter.toNic(nic, vmUuid, this::getNetworkById);
16021669
}
16031670

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/AsyncJobJoinVOToJobConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ protected static void fillAction(final ResourceAction action, final AsyncJobJoin
7878
public static VmAction toVmAction(final AsyncJobJoinVO vo, final UserVmJoinVO vm) {
7979
VmAction action = new VmAction();
8080
fillAction(action, vo);
81-
action.setVm(UserVmJoinVOToVmConverter.toVm(vm, null, null, null, null, null, null, false));
81+
action.setVm(UserVmJoinVOToVmConverter.toVm(vm, null, null, null, null, null, null, null, false));
8282
return action;
8383
}
8484

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/ImageTransferVOToImageTransferConverter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public static ImageTransfer toImageTransfer(ImageTransferVO vo, final Function<L
5252
} else if (org.apache.cloudstack.backup.ImageTransfer.Phase.failed.equals(vo.getPhase())) {
5353
imageTransfer.setPhase("finished_failed");
5454
}
55-
imageTransfer.setProxyUrl(vo.getTransferUrl());
5655
imageTransfer.setShallow(Boolean.toString(false));
5756
imageTransfer.setTimeoutPolicy("legacy");
5857
imageTransfer.setTransferUrl(vo.getTransferUrl());

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/converter/UserVmJoinVOToVmConverter.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
import com.cloud.api.query.vo.HostJoinVO;
4848
import com.cloud.api.query.vo.UserVmJoinVO;
49+
import com.cloud.network.security.SecurityGroupVO;
4950
import com.cloud.vm.VirtualMachine;
5051

5152
public final class UserVmJoinVOToVmConverter {
@@ -64,6 +65,7 @@ public static Vm toVm(final UserVmJoinVO src,
6465
final Function<Long, List<DiskAttachment>> disksResolver,
6566
final Function<UserVmJoinVO, List<Nic>> nicsResolver,
6667
final Function<UserVmJoinVO, SharedFS> sharedFsResolver,
68+
final Function<Long, List<SecurityGroupVO>> securityGroupsResolver,
6769
final boolean allContent) {
6870
if (src == null) {
6971
return null;
@@ -179,7 +181,11 @@ public static Vm toVm(final UserVmJoinVO src,
179181
dst.setGuestOsName(src.getGuestOsDisplayName());
180182
dst.setInstanceType(src.getUserVmType());
181183
updateSharedFSDetailsIfNeeded(src, sharedFsResolver, dst);
182-
dst.setSecurityGroupId(src.getSecurityGroupUuid());
184+
if (securityGroupsResolver != null) {
185+
dst.setSecurityGroupIds(securityGroupsResolver.apply(src.getId()).stream()
186+
.map(SecurityGroupVO::getUuid)
187+
.collect(Collectors.toList()));
188+
}
183189

184190
// Keep at end
185191
if (allContent) {
@@ -224,10 +230,11 @@ public static List<Vm> toVmList(final List<UserVmJoinVO> srcList,
224230
final Function<Long, List<DiskAttachment>> disksResolver,
225231
final Function<UserVmJoinVO, List<Nic>> nicsResolver,
226232
final Function<UserVmJoinVO, SharedFS> sharedFsResolver,
233+
final Function<Long, List<SecurityGroupVO>> securityGroupsResolver,
227234
final boolean allContent) {
228235
return srcList.stream()
229236
.map(v -> toVm(v, hostResolver, detailsResolver, tagsResolver, disksResolver,
230-
nicsResolver, sharedFsResolver, allContent))
237+
nicsResolver, sharedFsResolver, securityGroupsResolver, allContent))
231238
.collect(Collectors.toList());
232239
}
233240

plugins/integrations/veeam-control-service/src/main/java/org/apache/cloudstack/veeam/api/dto/OvfXmlUtil.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.IOException;
2222
import java.nio.charset.StandardCharsets;
2323
import java.text.SimpleDateFormat;
24+
import java.util.Arrays;
2425
import java.util.Date;
2526
import java.util.HashMap;
2627
import java.util.List;
@@ -487,8 +488,8 @@ private static void addCloudStackMetadata(Vm vm, UserVmJoinVO vo, StringBuilder
487488
sb.append("<SharedFSId>").append(escapeText(vm.getSharedFSId())).append("</SharedFSId>");
488489
sb.append("<SharedFSVolumeName>").append(escapeText(vm.getSharedFsVolumeName())).append("</SharedFSVolumeName>");
489490
}
490-
if (StringUtils.isNotBlank(vm.getSecurityGroupId())) {
491-
sb.append("<SecurityGroupId>").append(escapeText(vm.getSecurityGroupId())).append("</SecurityGroupId>");
491+
if (CollectionUtils.isNotEmpty(vm.getSecurityGroupIds())) {
492+
sb.append("<SecurityGroupIds>").append(escapeText(StringUtils.join(vm.getSecurityGroupIds(), ","))).append("</SecurityGroupIds>");
492493
}
493494
sb.append("</CloudStack>");
494495
sb.append("</Section>");
@@ -834,9 +835,9 @@ private static void updateFromXmlCloudStackMetadataSection(Vm vm, Node metadataS
834835
if (StringUtils.isNotBlank(sharedFSVolumeName)) {
835836
vm.setSharedFsVolumeName(sharedFSVolumeName);
836837
}
837-
String securityGroupId = xpathString(xpath, metadataSection, ".//*[local-name()='SecurityGroupId']/text()");
838-
if (StringUtils.isNotBlank(securityGroupId)) {
839-
vm.setInstanceType(securityGroupId);
838+
String securityGroupIds = xpathString(xpath, metadataSection, ".//*[local-name()='SecurityGroupIds']/text()");
839+
if (StringUtils.isNotBlank(securityGroupIds)) {
840+
vm.setSecurityGroupIds(Arrays.asList(StringUtils.split(securityGroupIds, ",")));
840841
}
841842
final Map<String, String> details = new HashMap<>();
842843
try {

0 commit comments

Comments
 (0)