From b4032d9984e5d2640a231edeb0363c491cddc2f9 Mon Sep 17 00:00:00 2001 From: dahn Date: Thu, 3 Aug 2023 16:06:11 +0200 Subject: [PATCH 1/3] include all VMs when projects selected not just for admins (#7667) --- .../java/com/cloud/api/query/QueryManagerImpl.java | 6 +++--- .../java/com/cloud/user/AccountManagerImpl.java | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java index 0968af0e7c0..5aad6afcdbb 100644 --- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java @@ -991,14 +991,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q private Pair, Integer> searchForUserVMsInternal(ListVMsCmd cmd) { Account caller = CallContext.current().getCallingAccount(); - List permittedAccounts = new ArrayList(); + List permittedAccounts = new ArrayList<>(); boolean listAll = cmd.listAll(); Long id = cmd.getId(); Long userId = cmd.getUserId(); Map tags = cmd.getTags(); Boolean display = cmd.getDisplay(); - Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + Ternary domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null); _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); @@ -1011,7 +1011,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q if (cmd.getIds() != null && !cmd.getIds().isEmpty()) { throw new InvalidParameterValueException("Specify either id or ids but not both parameters"); } - ids = new ArrayList(); + ids = new ArrayList<>(); ids.add(cmd.getId()); } else { ids = cmd.getIds(); diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 62a84d0d9bf..38b2eddeb60 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -2955,18 +2955,17 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (projectId != null) { if (!forProjectInvitation) { if (projectId == -1L) { - if (caller.getType() == Account.Type.ADMIN) { - domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly); - if (listAll) { - domainIdRecursiveListProject.third(ListProjectResourcesCriteria.ListAllIncludingProjectResources); - } - } else { + domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly); + if (caller.getType() != Account.Type.ADMIN) { permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId())); // permittedAccounts can be empty when the caller is not a part of any project (a domain account) - if (permittedAccounts.isEmpty()) { + if (permittedAccounts.isEmpty() || listAll) { permittedAccounts.add(caller.getId()); } } + if (listAll) { + domainIdRecursiveListProject.third(ListProjectResourcesCriteria.ListAllIncludingProjectResources); + } } else { Project project = _projectMgr.getProject(projectId); if (project == null) { From 57779a8586cd6578b87fe1f8d2506d62900a6814 Mon Sep 17 00:00:00 2001 From: kishankavala Date: Fri, 4 Aug 2023 12:12:38 +0530 Subject: [PATCH 2/3] Remove nic allocation txn during Vm deploy. During Vm deploy failure, this will allow cleanup of any nics that are successfully provisioned (#7809) --- .../orchestration/NetworkOrchestrator.java | 290 +++++++++--------- 1 file changed, 143 insertions(+), 147 deletions(-) diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 2f3e128bcaa..82e13b5c5b8 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -831,169 +831,165 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra public void allocate(final VirtualMachineProfile vm, final LinkedHashMap> networks, final Map> extraDhcpOptions) throws InsufficientCapacityException, ConcurrentOperationException { - Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { - @Override - public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException { - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size())); - } - int deviceId = 0; - int size; - size = determineNumberOfNicsRequired(); + if (s_logger.isTraceEnabled()) { + s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size())); + } + int deviceId = 0; + int size; + size = determineNumberOfNicsRequired(vm, networks); - final boolean[] deviceIds = new boolean[size]; - Arrays.fill(deviceIds, false); + final boolean[] deviceIds = new boolean[size]; + Arrays.fill(deviceIds, false); - List> profilesList = getOrderedNetworkNicProfileMapping(networks); - final List nics = new ArrayList(size); - NicProfile defaultNic = null; - Network nextNetwork = null; - for (Pair networkNicPair : profilesList) { - nextNetwork = networkNicPair.first(); - Pair newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic); - defaultNic = newDeviceInfo.first(); - deviceId = newDeviceInfo.second(); - } - createExtraNics(size, nics, nextNetwork); + List> profilesList = getOrderedNetworkNicProfileMapping(networks); + final List nics = new ArrayList(size); + NicProfile defaultNic = null; + Network nextNetwork = null; + for (Pair networkNicPair : profilesList) { + nextNetwork = networkNicPair.first(); + Pair newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(vm, extraDhcpOptions, networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic); + defaultNic = newDeviceInfo.first(); + deviceId = newDeviceInfo.second(); + } + createExtraNics(vm,size, nics, nextNetwork); - if (nics.size() == 1) { - nics.get(0).setDefaultNic(true); - } - } + if (nics.size() == 1) { + nics.get(0).setDefaultNic(true); + } + } - /** - * private transaction method to check and add devices to the nic list and update the info - */ - Pair addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List nics, NicProfile defaultNic) - throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException { - Pair rc = new Pair<>(null, null); - Boolean isDefaultNic = false; - if (vm != null && requested != null && requested.isDefaultNic()) { - isDefaultNic = true; - } + /** + * Method to check and add devices to the nic list and update the info + */ + private Pair addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(VirtualMachineProfile vm, Map> extraDhcpOptions, + NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List nics, NicProfile defaultNic) + throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException { + Pair rc = new Pair<>(null, null); + Boolean isDefaultNic = false; + if (vm != null && requested != null && requested.isDefaultNic()) { + isDefaultNic = true; + } - while (deviceIds[deviceId] && deviceId < deviceIds.length) { - deviceId++; - } + while (deviceIds[deviceId] && deviceId < deviceIds.length) { + deviceId++; + } - final Pair vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm); - NicProfile vmNic = null; - if (vmNicPair != null) { - vmNic = vmNicPair.first(); - if (vmNic == null) { - return rc; - } - deviceId = vmNicPair.second(); - } - - final int devId = vmNic.getDeviceId(); - if (devId >= deviceIds.length) { - throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); - } - if (deviceIds[devId]) { - throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); - } - - deviceIds[devId] = true; - - if (vmNic.isDefaultNic()) { - if (defaultNic != null) { - throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic); - } - defaultNic = vmNic; - } - - nics.add(vmNic); - vm.addNic(vmNic); - saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions); - rc.first(defaultNic); - rc.second(deviceId); + final Pair vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm); + NicProfile vmNic = null; + if (vmNicPair != null) { + vmNic = vmNicPair.first(); + if (vmNic == null) { return rc; } + deviceId = vmNicPair.second(); + } - /** - * private transaction method to get oredered list of Network and NicProfile pair - * @return ordered list of Network and NicProfile pair - * @param networks the map od networks to nic profiles list - */ - private List> getOrderedNetworkNicProfileMapping(final LinkedHashMap> networks) { - List> profilesList = new ArrayList<>(); - for (final Map.Entry> network : networks.entrySet()) { - List requestedProfiles = network.getValue(); - if (requestedProfiles == null) { - requestedProfiles = new ArrayList(); - } - if (requestedProfiles.isEmpty()) { - requestedProfiles.add(null); - } - for (final NicProfile requested : requestedProfiles) { - profilesList.add(new Pair(network.getKey(), requested)); - } - } - profilesList.sort(new Comparator>() { - @Override - public int compare(Pair pair1, Pair pair2) { - int profile1Order = Integer.MAX_VALUE; - int profile2Order = Integer.MAX_VALUE; - if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) { - profile1Order = pair1.second().getOrderIndex(); - } - if (pair2 != null && pair2.second() != null && pair2.second().getOrderIndex() != null) { - profile2Order = pair2.second().getOrderIndex(); - } - return profile1Order - profile2Order; - } - }); - return profilesList; + final int devId = vmNic.getDeviceId(); + if (devId >= deviceIds.length) { + throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); + } + if (deviceIds[devId]) { + throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); + } + + deviceIds[devId] = true; + + if (vmNic.isDefaultNic()) { + if (defaultNic != null) { + throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic); } + defaultNic = vmNic; + } - /** - * private transaction method to run over the objects and determine nic requirements - * @return the total numer of nics required - */ - private int determineNumberOfNicsRequired() { - int size = 0; - for (final Network ntwk : networks.keySet()) { - final List profiles = networks.get(ntwk); - if (profiles != null && !profiles.isEmpty()) { - size = size + profiles.size(); - } else { - size = size + 1; - } - } + nics.add(vmNic); + vm.addNic(vmNic); + saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions); + rc.first(defaultNic); + rc.second(deviceId); + return rc; + } - List netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); - if (size < netprereqs.size()) { - size = netprereqs.size(); - } - return size; + /** + * Method to get oredered list of Network and NicProfile pair + * @return ordered list of Network and NicProfile pair + * @param networks the map od networks to nic profiles list + */ + private List> getOrderedNetworkNicProfileMapping(final LinkedHashMap> networks) { + List> profilesList = new ArrayList<>(); + for (final Map.Entry> network : networks.entrySet()) { + List requestedProfiles = network.getValue(); + if (requestedProfiles == null) { + requestedProfiles = new ArrayList(); } - - /** - * private transaction method to add nics as required - * @param size the number needed - * @param nics the list of nics present - * @param finalNetwork the network to add the nics to - * @throws InsufficientVirtualNetworkCapacityException great - * @throws InsufficientAddressCapacityException also magnificent, as the name suggests - */ - private void createExtraNics(int size, List nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { - if (nics.size() != size) { - s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size); - if (nics.size() > size) { - throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size); - } else { - if (finalNetwork == null) { - throw new CloudRuntimeException(String.format("can not assign network to %d remaining required NICs", size - nics.size())); - } - // create extra - for (int extraNicNum = nics.size(); extraNicNum < size; extraNicNum++) { - final Pair vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm); - } - } + if (requestedProfiles.isEmpty()) { + requestedProfiles.add(null); + } + for (final NicProfile requested : requestedProfiles) { + profilesList.add(new Pair(network.getKey(), requested)); + } + } + profilesList.sort(new Comparator>() { + @Override + public int compare(Pair pair1, Pair pair2) { + int profile1Order = Integer.MAX_VALUE; + int profile2Order = Integer.MAX_VALUE; + if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) { + profile1Order = pair1.second().getOrderIndex(); } + if (pair2 != null && pair2.second() != null && pair2.second().getOrderIndex() != null) { + profile2Order = pair2.second().getOrderIndex(); + } + return profile1Order - profile2Order; } }); + return profilesList; + } + + /** + * private transaction method to run over the objects and determine nic requirements + * @return the total numer of nics required + */ + private int determineNumberOfNicsRequired(final VirtualMachineProfile vm, final LinkedHashMap> networks) { + int size = 0; + for (final Network ntwk : networks.keySet()) { + final List profiles = networks.get(ntwk); + if (profiles != null && !profiles.isEmpty()) { + size = size + profiles.size(); + } else { + size = size + 1; + } + } + + List netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); + if (size < netprereqs.size()) { + size = netprereqs.size(); + } + return size; + } + + /** + * Method to add nics as required + * @param size the number needed + * @param nics the list of nics present + * @param finalNetwork the network to add the nics to + * @throws InsufficientVirtualNetworkCapacityException great + * @throws InsufficientAddressCapacityException also magnificent, as the name suggests + */ + private void createExtraNics(final VirtualMachineProfile vm, int size, List nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + if (nics.size() != size) { + s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size); + if (nics.size() > size) { + throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size); + } else { + if (finalNetwork == null) { + throw new CloudRuntimeException(String.format("can not assign network to %d remaining required NICs", size - nics.size())); + } + // create extra + for (int extraNicNum = nics.size(); extraNicNum < size; extraNicNum++) { + final Pair vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm); + } + } + } } @Override From 6b21825746550ecf0bcb27d21e58af5eb5c63800 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 4 Aug 2023 08:44:29 +0200 Subject: [PATCH 3/3] make details optional for addGuestOs API (#7812) --- .../cloudstack/api/command/admin/guest/AddGuestOsCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java index 3adc711f35f..2b95c209bb8 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java @@ -57,7 +57,7 @@ public class AddGuestOsCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = false, description = "Optional name for Guest OS") private String osName; - @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = true, description = "Map of (key/value pairs)") + @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, required = false, description = "Map of (key/value pairs)") private Map details;