mirror of https://github.com/apache/cloudstack.git
Remove nic allocation txn during Vm deploy. During Vm deploy failure, this will allow cleanup of any nics that are successfully provisioned (#7809)
This commit is contained in:
parent
b4032d9984
commit
57779a8586
|
|
@ -831,169 +831,165 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||||
public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
|
public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
|
||||||
ConcurrentOperationException {
|
ConcurrentOperationException {
|
||||||
|
|
||||||
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
|
if (s_logger.isTraceEnabled()) {
|
||||||
@Override
|
s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size()));
|
||||||
public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
|
}
|
||||||
if (s_logger.isTraceEnabled()) {
|
int deviceId = 0;
|
||||||
s_logger.trace(String.format("allocating networks for %s(template %s); %d networks", vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size()));
|
int size;
|
||||||
}
|
size = determineNumberOfNicsRequired(vm, networks);
|
||||||
int deviceId = 0;
|
|
||||||
int size;
|
|
||||||
size = determineNumberOfNicsRequired();
|
|
||||||
|
|
||||||
final boolean[] deviceIds = new boolean[size];
|
final boolean[] deviceIds = new boolean[size];
|
||||||
Arrays.fill(deviceIds, false);
|
Arrays.fill(deviceIds, false);
|
||||||
|
|
||||||
List<Pair<Network, NicProfile>> profilesList = getOrderedNetworkNicProfileMapping(networks);
|
List<Pair<Network, NicProfile>> profilesList = getOrderedNetworkNicProfileMapping(networks);
|
||||||
final List<NicProfile> nics = new ArrayList<NicProfile>(size);
|
final List<NicProfile> nics = new ArrayList<NicProfile>(size);
|
||||||
NicProfile defaultNic = null;
|
NicProfile defaultNic = null;
|
||||||
Network nextNetwork = null;
|
Network nextNetwork = null;
|
||||||
for (Pair<Network, NicProfile> networkNicPair : profilesList) {
|
for (Pair<Network, NicProfile> networkNicPair : profilesList) {
|
||||||
nextNetwork = networkNicPair.first();
|
nextNetwork = networkNicPair.first();
|
||||||
Pair<NicProfile, Integer> newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic);
|
Pair<NicProfile, Integer> newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(vm, extraDhcpOptions, networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic);
|
||||||
defaultNic = newDeviceInfo.first();
|
defaultNic = newDeviceInfo.first();
|
||||||
deviceId = newDeviceInfo.second();
|
deviceId = newDeviceInfo.second();
|
||||||
}
|
}
|
||||||
createExtraNics(size, nics, nextNetwork);
|
createExtraNics(vm,size, nics, nextNetwork);
|
||||||
|
|
||||||
if (nics.size() == 1) {
|
if (nics.size() == 1) {
|
||||||
nics.get(0).setDefaultNic(true);
|
nics.get(0).setDefaultNic(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private transaction method to check and add devices to the nic list and update the info
|
* Method to check and add devices to the nic list and update the info
|
||||||
*/
|
*/
|
||||||
Pair<NicProfile, Integer> addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List<NicProfile> nics, NicProfile defaultNic)
|
private Pair<NicProfile, Integer> addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(VirtualMachineProfile vm, Map<String, Map<Integer, String>> extraDhcpOptions,
|
||||||
throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException {
|
NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List<NicProfile> nics, NicProfile defaultNic)
|
||||||
Pair<NicProfile, Integer> rc = new Pair<>(null, null);
|
throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException {
|
||||||
Boolean isDefaultNic = false;
|
Pair<NicProfile, Integer> rc = new Pair<>(null, null);
|
||||||
if (vm != null && requested != null && requested.isDefaultNic()) {
|
Boolean isDefaultNic = false;
|
||||||
isDefaultNic = true;
|
if (vm != null && requested != null && requested.isDefaultNic()) {
|
||||||
}
|
isDefaultNic = true;
|
||||||
|
}
|
||||||
|
|
||||||
while (deviceIds[deviceId] && deviceId < deviceIds.length) {
|
while (deviceIds[deviceId] && deviceId < deviceIds.length) {
|
||||||
deviceId++;
|
deviceId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm);
|
final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm);
|
||||||
NicProfile vmNic = null;
|
NicProfile vmNic = null;
|
||||||
if (vmNicPair != null) {
|
if (vmNicPair != null) {
|
||||||
vmNic = vmNicPair.first();
|
vmNic = vmNicPair.first();
|
||||||
if (vmNic == null) {
|
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);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
deviceId = vmNicPair.second();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
final int devId = vmNic.getDeviceId();
|
||||||
* private transaction method to get oredered list of Network and NicProfile pair
|
if (devId >= deviceIds.length) {
|
||||||
* @return ordered list of Network and NicProfile pair
|
throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
|
||||||
* @param networks the map od networks to nic profiles list
|
}
|
||||||
*/
|
if (deviceIds[devId]) {
|
||||||
private List<Pair<Network, NicProfile>> getOrderedNetworkNicProfileMapping(final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
|
throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
|
||||||
List<Pair<Network, NicProfile>> profilesList = new ArrayList<>();
|
}
|
||||||
for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
|
|
||||||
List<? extends NicProfile> requestedProfiles = network.getValue();
|
deviceIds[devId] = true;
|
||||||
if (requestedProfiles == null) {
|
|
||||||
requestedProfiles = new ArrayList<NicProfile>();
|
if (vmNic.isDefaultNic()) {
|
||||||
}
|
if (defaultNic != null) {
|
||||||
if (requestedProfiles.isEmpty()) {
|
throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
|
||||||
requestedProfiles.add(null);
|
|
||||||
}
|
|
||||||
for (final NicProfile requested : requestedProfiles) {
|
|
||||||
profilesList.add(new Pair<Network, NicProfile>(network.getKey(), requested));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
profilesList.sort(new Comparator<Pair<Network, NicProfile>>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Pair<Network, NicProfile> pair1, Pair<Network, NicProfile> 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;
|
|
||||||
}
|
}
|
||||||
|
defaultNic = vmNic;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
nics.add(vmNic);
|
||||||
* private transaction method to run over the objects and determine nic requirements
|
vm.addNic(vmNic);
|
||||||
* @return the total numer of nics required
|
saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions);
|
||||||
*/
|
rc.first(defaultNic);
|
||||||
private int determineNumberOfNicsRequired() {
|
rc.second(deviceId);
|
||||||
int size = 0;
|
return rc;
|
||||||
for (final Network ntwk : networks.keySet()) {
|
}
|
||||||
final List<? extends NicProfile> profiles = networks.get(ntwk);
|
|
||||||
if (profiles != null && !profiles.isEmpty()) {
|
|
||||||
size = size + profiles.size();
|
|
||||||
} else {
|
|
||||||
size = size + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
|
/**
|
||||||
if (size < netprereqs.size()) {
|
* Method to get oredered list of Network and NicProfile pair
|
||||||
size = netprereqs.size();
|
* @return ordered list of Network and NicProfile pair
|
||||||
}
|
* @param networks the map od networks to nic profiles list
|
||||||
return size;
|
*/
|
||||||
|
private List<Pair<Network, NicProfile>> getOrderedNetworkNicProfileMapping(final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
|
||||||
|
List<Pair<Network, NicProfile>> profilesList = new ArrayList<>();
|
||||||
|
for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
|
||||||
|
List<? extends NicProfile> requestedProfiles = network.getValue();
|
||||||
|
if (requestedProfiles == null) {
|
||||||
|
requestedProfiles = new ArrayList<NicProfile>();
|
||||||
}
|
}
|
||||||
|
if (requestedProfiles.isEmpty()) {
|
||||||
/**
|
requestedProfiles.add(null);
|
||||||
* private transaction method to add nics as required
|
}
|
||||||
* @param size the number needed
|
for (final NicProfile requested : requestedProfiles) {
|
||||||
* @param nics the list of nics present
|
profilesList.add(new Pair<Network, NicProfile>(network.getKey(), requested));
|
||||||
* @param finalNetwork the network to add the nics to
|
}
|
||||||
* @throws InsufficientVirtualNetworkCapacityException great
|
}
|
||||||
* @throws InsufficientAddressCapacityException also magnificent, as the name suggests
|
profilesList.sort(new Comparator<Pair<Network, NicProfile>>() {
|
||||||
*/
|
@Override
|
||||||
private void createExtraNics(int size, List<NicProfile> nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
|
public int compare(Pair<Network, NicProfile> pair1, Pair<Network, NicProfile> pair2) {
|
||||||
if (nics.size() != size) {
|
int profile1Order = Integer.MAX_VALUE;
|
||||||
s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
|
int profile2Order = Integer.MAX_VALUE;
|
||||||
if (nics.size() > size) {
|
if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) {
|
||||||
throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
|
profile1Order = pair1.second().getOrderIndex();
|
||||||
} 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<NicProfile, Integer> vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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<? extends Network, List<? extends NicProfile>> networks) {
|
||||||
|
int size = 0;
|
||||||
|
for (final Network ntwk : networks.keySet()) {
|
||||||
|
final List<? extends NicProfile> profiles = networks.get(ntwk);
|
||||||
|
if (profiles != null && !profiles.isEmpty()) {
|
||||||
|
size = size + profiles.size();
|
||||||
|
} else {
|
||||||
|
size = size + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OVFNetworkTO> 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<NicProfile> 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<NicProfile, Integer> vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue