|
23 | 23 | import java.util.Arrays; |
24 | 24 | import java.util.Date; |
25 | 25 | import java.util.HashMap; |
| 26 | +import java.util.HashSet; |
26 | 27 | import java.util.List; |
27 | 28 | import java.util.Map; |
| 29 | +import java.util.Set; |
28 | 30 | import java.util.UUID; |
29 | 31 | import java.util.concurrent.ExecutionException; |
30 | 32 | import java.util.concurrent.ExecutorService; |
|
151 | 153 | import com.cloud.hypervisor.Hypervisor.HypervisorType; |
152 | 154 | import com.cloud.hypervisor.HypervisorGuru; |
153 | 155 | import com.cloud.hypervisor.HypervisorGuruManager; |
| 156 | +import com.cloud.network.Network.Provider; |
| 157 | +import com.cloud.network.Network.Service; |
| 158 | +import com.cloud.network.NetworkModel; |
| 159 | +import com.cloud.network.element.ConfigDriveNetworkElement; |
154 | 160 | import com.cloud.projects.Project; |
155 | 161 | import com.cloud.projects.ProjectManager; |
156 | 162 | import com.cloud.resourcelimit.CheckedReservation; |
|
215 | 221 | import com.cloud.utils.db.TransactionCallbackNoReturn; |
216 | 222 | import com.cloud.utils.db.TransactionStatus; |
217 | 223 | import com.cloud.utils.exception.CloudRuntimeException; |
| 224 | +import com.cloud.vm.NicVO; |
218 | 225 | import com.cloud.vm.UserVmManager; |
219 | 226 | import com.cloud.vm.UserVmVO; |
220 | 227 | import com.cloud.vm.VMInstanceVO; |
|
223 | 230 | import com.cloud.vm.VirtualMachineProfile; |
224 | 231 | import com.cloud.vm.VirtualMachineProfileImpl; |
225 | 232 | import com.cloud.vm.VmDetailConstants; |
| 233 | +import com.cloud.vm.dao.NicDao; |
226 | 234 | import com.cloud.vm.dao.UserVmDao; |
227 | 235 | import com.cloud.vm.dao.VMInstanceDao; |
| 236 | +import com.cloud.vm.dao.VMInstanceDetailsDao; |
228 | 237 | import com.google.gson.Gson; |
229 | 238 | import com.google.gson.GsonBuilder; |
230 | 239 |
|
@@ -324,6 +333,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, |
324 | 333 | private HeuristicRuleHelper heuristicRuleHelper; |
325 | 334 | @Inject |
326 | 335 | private UserDataDao userDataDao; |
| 336 | + @Inject |
| 337 | + private NicDao _nicDao; |
| 338 | + @Inject |
| 339 | + private NetworkModel _networkModel; |
| 340 | + @Inject |
| 341 | + private VMInstanceDetailsDao _vmInstanceDetailsDao; |
327 | 342 |
|
328 | 343 | private List<TemplateAdapter> _adapters; |
329 | 344 |
|
@@ -730,6 +745,61 @@ public void prepareIsoForVmProfile(VirtualMachineProfile profile, DeployDestinat |
730 | 745 | } |
731 | 746 | } |
732 | 747 |
|
| 748 | + @Override |
| 749 | + public Set<Long> getCdromDeviceIds(VirtualMachine vm) { |
| 750 | + if (vm.getType() != VirtualMachine.Type.User) { |
| 751 | + return getCdromDeviceIds(1); |
| 752 | + } |
| 753 | + return getCdromDeviceIds(vm, isConfigDriveUsed(vm)); |
| 754 | + } |
| 755 | + |
| 756 | + @Override |
| 757 | + public Set<Long> getCdromDeviceIds(VirtualMachine vm, boolean configDriveUsed) { |
| 758 | + return getCdromDeviceIds(getCdromCount(vm, configDriveUsed)); |
| 759 | + } |
| 760 | + |
| 761 | + private Set<Long> getCdromDeviceIds(int cdromCount) { |
| 762 | + Set<Long> deviceIds = new HashSet<>(); |
| 763 | + for (int i = 0; i < cdromCount; i++) { |
| 764 | + deviceIds.add((long) CDROM_PRIMARY_DEVICE_SEQ + i); |
| 765 | + } |
| 766 | + return deviceIds; |
| 767 | + } |
| 768 | + |
| 769 | + private int getCdromCount(VirtualMachine vm, boolean configDriveUsed) { |
| 770 | + // an Instance has one CD-ROM device for its ISO |
| 771 | + int cdromCount = 1; |
| 772 | + // the config drive ISO is one more CD-ROM, which has the device id of ConfigDriveNetworkElement#CONFIGDRIVEDISKSEQ |
| 773 | + if (vm.getType() == VirtualMachine.Type.User && configDriveUsed) { |
| 774 | + cdromCount += ConfigDriveNetworkElement.CONFIGDRIVEDISKSEQ - CDROM_PRIMARY_DEVICE_SEQ; |
| 775 | + } |
| 776 | + return cdromCount; |
| 777 | + } |
| 778 | + |
| 779 | + /** |
| 780 | + * Checks if a config drive ISO is (or will be) attached to the Instance, which is the case when any of its networks |
| 781 | + * has ConfigDrive as the provider of the Dhcp, Dns or UserData service. Checking the network providers (instead of |
| 782 | + * only the config drive location detail, which is added when the ISO is created) also covers Instances which have |
| 783 | + * never been started. |
| 784 | + */ |
| 785 | + boolean isConfigDriveUsed(VirtualMachine vm) { |
| 786 | + if (_vmInstanceDetailsDao.findDetail(vm.getId(), VmDetailConstants.CONFIG_DRIVE_LOCATION) != null) { |
| 787 | + return true; |
| 788 | + } |
| 789 | + List<NicVO> nics = _nicDao.listByVmId(vm.getId()); |
| 790 | + if (CollectionUtils.isEmpty(nics)) { |
| 791 | + return false; |
| 792 | + } |
| 793 | + for (NicVO nic : nics) { |
| 794 | + for (Service service : Arrays.asList(Service.UserData, Service.Dhcp, Service.Dns)) { |
| 795 | + if (_networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), service, Provider.ConfigDrive)) { |
| 796 | + return true; |
| 797 | + } |
| 798 | + } |
| 799 | + } |
| 800 | + return false; |
| 801 | + } |
| 802 | + |
733 | 803 | private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) { |
734 | 804 | logger.info("Schedule to preload Template {} into primary storage {}", template, pool); |
735 | 805 | if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) { |
|
0 commit comments