Skip to content

Commit 57779a8

Browse files
authored
Remove nic allocation txn during Vm deploy. During Vm deploy failure, this will allow cleanup of any nics that are successfully provisioned (#7809)
1 parent b4032d9 commit 57779a8

File tree

1 file changed

+143
-147
lines changed

1 file changed

+143
-147
lines changed

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 143 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -831,169 +831,165 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
831831
public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
832832
ConcurrentOperationException {
833833

834-
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
835-
@Override
836-
public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
837-
if (s_logger.isTraceEnabled()) {
838-
s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size()));
839-
}
840-
int deviceId = 0;
841-
int size;
842-
size = determineNumberOfNicsRequired();
843-
844-
final boolean[] deviceIds = new boolean[size];
845-
Arrays.fill(deviceIds, false);
846-
847-
List<Pair<Network, NicProfile>> profilesList = getOrderedNetworkNicProfileMapping(networks);
848-
final List<NicProfile> nics = new ArrayList<NicProfile>(size);
849-
NicProfile defaultNic = null;
850-
Network nextNetwork = null;
851-
for (Pair<Network, NicProfile> networkNicPair : profilesList) {
852-
nextNetwork = networkNicPair.first();
853-
Pair<NicProfile, Integer> newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic);
854-
defaultNic = newDeviceInfo.first();
855-
deviceId = newDeviceInfo.second();
856-
}
857-
createExtraNics(size, nics, nextNetwork);
834+
if (s_logger.isTraceEnabled()) {
835+
s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size()));
836+
}
837+
int deviceId = 0;
838+
int size;
839+
size = determineNumberOfNicsRequired(vm, networks);
858840

859-
if (nics.size() == 1) {
860-
nics.get(0).setDefaultNic(true);
861-
}
862-
}
841+
final boolean[] deviceIds = new boolean[size];
842+
Arrays.fill(deviceIds, false);
863843

864-
/**
865-
* private transaction method to check and add devices to the nic list and update the info
866-
*/
867-
Pair<NicProfile, Integer> addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List<NicProfile> nics, NicProfile defaultNic)
868-
throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException {
869-
Pair<NicProfile, Integer> rc = new Pair<>(null, null);
870-
Boolean isDefaultNic = false;
871-
if (vm != null && requested != null && requested.isDefaultNic()) {
872-
isDefaultNic = true;
873-
}
844+
List<Pair<Network, NicProfile>> profilesList = getOrderedNetworkNicProfileMapping(networks);
845+
final List<NicProfile> nics = new ArrayList<NicProfile>(size);
846+
NicProfile defaultNic = null;
847+
Network nextNetwork = null;
848+
for (Pair<Network, NicProfile> networkNicPair : profilesList) {
849+
nextNetwork = networkNicPair.first();
850+
Pair<NicProfile, Integer> newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(vm, extraDhcpOptions, networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic);
851+
defaultNic = newDeviceInfo.first();
852+
deviceId = newDeviceInfo.second();
853+
}
854+
createExtraNics(vm,size, nics, nextNetwork);
874855

875-
while (deviceIds[deviceId] && deviceId < deviceIds.length) {
876-
deviceId++;
877-
}
856+
if (nics.size() == 1) {
857+
nics.get(0).setDefaultNic(true);
858+
}
859+
}
878860

879-
final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm);
880-
NicProfile vmNic = null;
881-
if (vmNicPair != null) {
882-
vmNic = vmNicPair.first();
883-
if (vmNic == null) {
884-
return rc;
885-
}
886-
deviceId = vmNicPair.second();
887-
}
861+
/**
862+
* Method to check and add devices to the nic list and update the info
863+
*/
864+
private Pair<NicProfile, Integer> addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(VirtualMachineProfile vm, Map<String, Map<Integer, String>> extraDhcpOptions,
865+
NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List<NicProfile> nics, NicProfile defaultNic)
866+
throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException {
867+
Pair<NicProfile, Integer> rc = new Pair<>(null, null);
868+
Boolean isDefaultNic = false;
869+
if (vm != null && requested != null && requested.isDefaultNic()) {
870+
isDefaultNic = true;
871+
}
888872

889-
final int devId = vmNic.getDeviceId();
890-
if (devId >= deviceIds.length) {
891-
throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
892-
}
893-
if (deviceIds[devId]) {
894-
throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
895-
}
873+
while (deviceIds[deviceId] && deviceId < deviceIds.length) {
874+
deviceId++;
875+
}
896876

897-
deviceIds[devId] = true;
877+
final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm);
878+
NicProfile vmNic = null;
879+
if (vmNicPair != null) {
880+
vmNic = vmNicPair.first();
881+
if (vmNic == null) {
882+
return rc;
883+
}
884+
deviceId = vmNicPair.second();
885+
}
898886

899-
if (vmNic.isDefaultNic()) {
900-
if (defaultNic != null) {
901-
throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
902-
}
903-
defaultNic = vmNic;
904-
}
887+
final int devId = vmNic.getDeviceId();
888+
if (devId >= deviceIds.length) {
889+
throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
890+
}
891+
if (deviceIds[devId]) {
892+
throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
893+
}
905894

906-
nics.add(vmNic);
907-
vm.addNic(vmNic);
908-
saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions);
909-
rc.first(defaultNic);
910-
rc.second(deviceId);
911-
return rc;
895+
deviceIds[devId] = true;
896+
897+
if (vmNic.isDefaultNic()) {
898+
if (defaultNic != null) {
899+
throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
912900
}
901+
defaultNic = vmNic;
902+
}
913903

914-
/**
915-
* private transaction method to get oredered list of Network and NicProfile pair
916-
* @return ordered list of Network and NicProfile pair
917-
* @param networks the map od networks to nic profiles list
918-
*/
919-
private List<Pair<Network, NicProfile>> getOrderedNetworkNicProfileMapping(final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
920-
List<Pair<Network, NicProfile>> profilesList = new ArrayList<>();
921-
for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
922-
List<? extends NicProfile> requestedProfiles = network.getValue();
923-
if (requestedProfiles == null) {
924-
requestedProfiles = new ArrayList<NicProfile>();
925-
}
926-
if (requestedProfiles.isEmpty()) {
927-
requestedProfiles.add(null);
928-
}
929-
for (final NicProfile requested : requestedProfiles) {
930-
profilesList.add(new Pair<Network, NicProfile>(network.getKey(), requested));
931-
}
904+
nics.add(vmNic);
905+
vm.addNic(vmNic);
906+
saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions);
907+
rc.first(defaultNic);
908+
rc.second(deviceId);
909+
return rc;
910+
}
911+
912+
/**
913+
* Method to get oredered list of Network and NicProfile pair
914+
* @return ordered list of Network and NicProfile pair
915+
* @param networks the map od networks to nic profiles list
916+
*/
917+
private List<Pair<Network, NicProfile>> getOrderedNetworkNicProfileMapping(final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
918+
List<Pair<Network, NicProfile>> profilesList = new ArrayList<>();
919+
for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
920+
List<? extends NicProfile> requestedProfiles = network.getValue();
921+
if (requestedProfiles == null) {
922+
requestedProfiles = new ArrayList<NicProfile>();
923+
}
924+
if (requestedProfiles.isEmpty()) {
925+
requestedProfiles.add(null);
926+
}
927+
for (final NicProfile requested : requestedProfiles) {
928+
profilesList.add(new Pair<Network, NicProfile>(network.getKey(), requested));
929+
}
930+
}
931+
profilesList.sort(new Comparator<Pair<Network, NicProfile>>() {
932+
@Override
933+
public int compare(Pair<Network, NicProfile> pair1, Pair<Network, NicProfile> pair2) {
934+
int profile1Order = Integer.MAX_VALUE;
935+
int profile2Order = Integer.MAX_VALUE;
936+
if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) {
937+
profile1Order = pair1.second().getOrderIndex();
932938
}
933-
profilesList.sort(new Comparator<Pair<Network, NicProfile>>() {
934-
@Override
935-
public int compare(Pair<Network, NicProfile> pair1, Pair<Network, NicProfile> pair2) {
936-
int profile1Order = Integer.MAX_VALUE;
937-
int profile2Order = Integer.MAX_VALUE;
938-
if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) {
939-
profile1Order = pair1.second().getOrderIndex();
940-
}
941-
if (pair2 != null && pair2.second() != null && pair2.second().getOrderIndex() != null) {
942-
profile2Order = pair2.second().getOrderIndex();
943-
}
944-
return profile1Order - profile2Order;
945-
}
946-
});
947-
return profilesList;
948-
}
949-
950-
/**
951-
* private transaction method to run over the objects and determine nic requirements
952-
* @return the total numer of nics required
953-
*/
954-
private int determineNumberOfNicsRequired() {
955-
int size = 0;
956-
for (final Network ntwk : networks.keySet()) {
957-
final List<? extends NicProfile> profiles = networks.get(ntwk);
958-
if (profiles != null && !profiles.isEmpty()) {
959-
size = size + profiles.size();
960-
} else {
961-
size = size + 1;
962-
}
939+
if (pair2 != null && pair2.second() != null && pair2.second().getOrderIndex() != null) {
940+
profile2Order = pair2.second().getOrderIndex();
963941
}
942+
return profile1Order - profile2Order;
943+
}
944+
});
945+
return profilesList;
946+
}
947+
948+
/**
949+
* private transaction method to run over the objects and determine nic requirements
950+
* @return the total numer of nics required
951+
*/
952+
private int determineNumberOfNicsRequired(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
953+
int size = 0;
954+
for (final Network ntwk : networks.keySet()) {
955+
final List<? extends NicProfile> profiles = networks.get(ntwk);
956+
if (profiles != null && !profiles.isEmpty()) {
957+
size = size + profiles.size();
958+
} else {
959+
size = size + 1;
960+
}
961+
}
964962

965-
List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
966-
if (size < netprereqs.size()) {
967-
size = netprereqs.size();
963+
List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
964+
if (size < netprereqs.size()) {
965+
size = netprereqs.size();
966+
}
967+
return size;
968+
}
969+
970+
/**
971+
* Method to add nics as required
972+
* @param size the number needed
973+
* @param nics the list of nics present
974+
* @param finalNetwork the network to add the nics to
975+
* @throws InsufficientVirtualNetworkCapacityException great
976+
* @throws InsufficientAddressCapacityException also magnificent, as the name suggests
977+
*/
978+
private void createExtraNics(final VirtualMachineProfile vm, int size, List<NicProfile> nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
979+
if (nics.size() != size) {
980+
s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
981+
if (nics.size() > size) {
982+
throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
983+
} else {
984+
if (finalNetwork == null) {
985+
throw new CloudRuntimeException(String.format("can not assign network to %d remaining required NICs", size - nics.size()));
968986
}
969-
return size;
970-
}
971-
972-
/**
973-
* private transaction method to add nics as required
974-
* @param size the number needed
975-
* @param nics the list of nics present
976-
* @param finalNetwork the network to add the nics to
977-
* @throws InsufficientVirtualNetworkCapacityException great
978-
* @throws InsufficientAddressCapacityException also magnificent, as the name suggests
979-
*/
980-
private void createExtraNics(int size, List<NicProfile> nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
981-
if (nics.size() != size) {
982-
s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
983-
if (nics.size() > size) {
984-
throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
985-
} else {
986-
if (finalNetwork == null) {
987-
throw new CloudRuntimeException(String.format("can not assign network to %d remaining required NICs", size - nics.size()));
988-
}
989-
// create extra
990-
for (int extraNicNum = nics.size(); extraNicNum < size; extraNicNum++) {
991-
final Pair<NicProfile, Integer> vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm);
992-
}
993-
}
987+
// create extra
988+
for (int extraNicNum = nics.size(); extraNicNum < size; extraNicNum++) {
989+
final Pair<NicProfile, Integer> vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm);
994990
}
995991
}
996-
});
992+
}
997993
}
998994

999995
@Override

0 commit comments

Comments
 (0)