public VmInstanceInventory(VmInstanceInventory origin) { VmInstanceInventory inv; try { inv = (VmInstanceInventory) origin.clone(); } catch (CloneNotSupportedException e) { throw new CloudRuntimeException(e); } this.setClusterUuid(inv.getClusterUuid()); this.setCreateDate(inv.getCreateDate()); this.setDescription(inv.getDescription()); this.setHostUuid(inv.getHostUuid()); this.setHypervisorType(inv.getHypervisorType()); this.setImageUuid(inv.getImageUuid()); this.setInstanceOfferingUuid(inv.getInstanceOfferingUuid()); this.setLastHostUuid(inv.getLastHostUuid()); this.setLastOpDate(inv.getLastOpDate()); this.setName(inv.getName()); this.setRootVolumeUuid(inv.getRootVolumeUuid()); this.setState(inv.getState()); this.setType(inv.getType()); this.setUuid(inv.getUuid()); this.setZoneUuid(inv.getZoneUuid()); this.setAllVolumes(inv.getAllVolumes()); this.setVmNics(inv.getVmNics()); this.setInternalId(inv.getInternalId()); this.setCpuNum(inv.getCpuNum()); this.setCpuSpeed(inv.getCpuSpeed()); this.setMemorySize(inv.getMemorySize()); this.setAllocatorStrategy(inv.getAllocatorStrategy()); }
public static List<VmInstanceInventory> valueOf(Collection<VmInstanceVO> vos) { List<VmInstanceInventory> invs = new ArrayList<VmInstanceInventory>(vos.size()); for (VmInstanceVO vo : vos) { invs.add(VmInstanceInventory.valueOf(vo)); } return invs; }
public void setParametersFromVmInventory(VmInstanceInventory inv) { vmUuid = inv.getUuid(); vmNics = inv.getVmNics(); hostUuid = inv.getHostUuid(); }
@Override public String getHostUuid() { if (vmInventory.getHostUuid() != null) { return vmInventory.getHostUuid(); } else { return vmInventory.getLastHostUuid(); } } }
@Override public void fail(ErrorCode errorCode) { logger.debug(String.format("vm[uuid:%s, name:%s] migrated to host[uuid:%s], failed to cleanup its old rules on host[uuid:%s] if needed", inv.getUuid(), inv.getName(), inv.getHostUuid(), srcHostUuid)); createFailureHostTask(inv.getLastHostUuid()); } });
@Override public void fail(ErrorCode errorCode) { logger.warn(String.format("failed to release userdata on the source host[uuid:%s]" + " for the migrated VM[uuid: %s, name:%s], %s. GC will take care it", srcHostUuid, inv.getUuid(), inv.getName(), errorCode)); UserdataReleseGC gc = new UserdataReleseGC(); gc.struct = struct; gc.submit(UserdataReleseGC.INTERVAL, TimeUnit.SECONDS); } });
@Override public void success() { logger.debug(String.format("vm[uuid:%s, name:%s] migrated to host[uuid:%s], cleanup its old rules on host[uuid:%s] if needed", inv.getUuid(), inv.getName(), inv.getHostUuid(), srcHostUuid)); }
List<String> nicUuidToDel = CollectionUtils.transformToList(inv.getVmNics(), new Function<String, VmNicInventory>() { @Override public String call(VmNicInventory arg) { self = dbf.findByUuid(inv.getUuid(), VmInstanceVO.class); inv = VmInstanceInventory.valueOf(self); spec.setDestNics(inv.getVmNics()); List<VmNicSpec> nicSpecs = new ArrayList<>(); for (VmNicInventory nic : inv.getVmNics()) { List<L3NetworkInventory> l3Invs = new ArrayList<>(); List<String> secondaryNetworksList = new DualStackNicSecondaryNetworksOperator().getSecondaryNetworksByVmUuidNic(inv.getUuid(), nic.getL3NetworkUuid()); if (secondaryNetworksList != null && !secondaryNetworksList.isEmpty()) { for (String uuid : secondaryNetworksList) { String huuid = inv.getHostUuid() == null ? inv.getLastHostUuid() : inv.getHostUuid(); if (huuid != null) { HostVO hvo = dbf.findByUuid(huuid, HostVO.class); for (VolumeInventory vol : inv.getAllVolumes()) { if (vol.getUuid().equals(inv.getRootVolumeUuid())) { spec.setDestRootVolume(vol); spec.setRequiredPrimaryStorageUuidForRootVolume(vol.getPrimaryStorageUuid()); String vmUuid = inv.getUuid(); exts.forEach(e -> dataVols.addAll(e.supplyAdditionalVolumesForVmInstance(vmUuid))); if (inv.getImageUuid() != null) {
@Override @Transactional(readOnly = true) public void preRecoverVm(VmInstanceInventory vm) { String rootVolUuid = vm.getRootVolumeUuid(); String sql = "select ps.uuid" + " from PrimaryStorageVO ps, VolumeVO vol" + " where ps.uuid = vol.primaryStorageUuid" + " and vol.uuid = :uuid" + " and ps.type = :pstype"; TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("uuid", rootVolUuid); q.setParameter("pstype", LocalStorageConstants.LOCAL_STORAGE_TYPE); String psuuid = dbf.find(q); if (psuuid == null) { return; } sql = "select count(ref)" + " from LocalStorageResourceRefVO ref" + " where ref.resourceUuid = :uuid" + " and ref.resourceType = :rtype"; TypedQuery<Long> rq = dbf.getEntityManager().createQuery(sql, Long.class); rq.setParameter("uuid", rootVolUuid); rq.setParameter("rtype", VolumeVO.class.getSimpleName()); long count = rq.getSingleResult(); if (count == 0) { throw new OperationFailureException(operr("unable to recover the vm[uuid:%s, name:%s]. The vm's root volume is on the local" + " storage[uuid:%s]; however, the host on which the root volume is has been deleted", vm.getUuid(), vm.getName(), psuuid)); } }
@Override public void addAddon(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { if (!spec.getVmInventory().getType().equals(ApplianceVmConstant.APPLIANCE_VM_TYPE)) { return; } KVMAddons.Channel chan = new KVMAddons.Channel(); chan.setSocketPath(makeChannelSocketPath(spec.getVmInventory().getUuid())); chan.setTargetName(String.format("applianceVm.vport")); cmd.getAddons().put(chan.NAME, chan); logger.debug(String.format("make kvm channel device[path:%s, target:%s]", chan.getSocketPath(), chan.getTargetName())); }
@Override public String getVmInstanceUuid() { return getVmInstance().getUuid(); } }
@Override public void failedToMigrateVm(final VmInstanceInventory inv, final String destHostUuid, ErrorCode reason) { RuleCalculator cal = new RuleCalculator(); cal.vmNicUuids = CollectionUtils.transformToList(inv.getVmNics(), new Function<String, VmNicInventory>() { @Override public String call(VmNicInventory arg) { return arg.getUuid(); } }); cal.vmStates = asList(VmInstanceState.Unknown); List<HostRuleTO> htos = cal.calculate(); logger.debug(String.format("vm[uuid:%s, name:%s] failed to migrate to host[uuid:%s], recover its rules on previous host[uuid:%s]", inv.getUuid(), inv.getName(), destHostUuid, inv.getHostUuid())); applyRules(htos); }
String platform = spec.getVmInventory().getPlatform() == null ? spec.getImageSpec().getInventory().getPlatform() : spec.getVmInventory().getPlatform(); virtio = VmSystemTags.WINDOWS_VOLUME_ON_VIRTIO.hasTag(spec.getVmInventory().getUuid()); } else { virtio = ImagePlatform.valueOf(platform).isParaVirtualization(); int cpuNum = spec.getVmInventory().getCpuNum(); cmd.setCpuNum(cpuNum); cmd.setVmName(spec.getVmInventory().getName()); cmd.setVmInstanceUuid(spec.getVmInventory().getUuid()); cmd.setCpuSpeed(spec.getVmInventory().getCpuSpeed()); cmd.setMemory(spec.getVmInventory().getMemorySize()); cmd.setMaxMemory(self.getCapacity().getTotalPhysicalMemory()); cmd.setClock(ImagePlatform.isType(platform, ImagePlatform.Windows, ImagePlatform.WindowsVirtio) ? "localtime" : "utc"); cmd.setVideoType(VmGlobalConfig.VM_VIDEO_TYPE.value(String.class)); cmd.setInstanceOfferingOnlineChange(VmSystemTags.INSTANCEOFFERING_ONLIECHANGE.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmSystemTags.INSTANCEOFFERING_ONLINECHANGE_TOKEN) != null); cmd.setKvmHiddenState(VmGlobalConfig.KVM_HIDDEN_STATE.value(Boolean.class)); cmd.setSpiceStreamingMode(VmGlobalConfig.VM_SPICE_STREAMING_MODE.value(String.class)); cmd.setEmulateHyperV(VmGlobalConfig.EMULATE_HYPERV.value(Boolean.class)); cmd.setAdditionalQmp(VmGlobalConfig.ADDITIONAL_QMP.value(Boolean.class)); cmd.setApplianceVm(spec.getVmInventory().getType().equals("ApplianceVm")); cmd.setSystemSerialNumber(makeAndSaveVmSystemSerialNumber(spec.getVmInventory().getUuid())); cmd.setVmInternalId(spec.getVmInventory().getInternalId()); String bootMode = VmSystemTags.BOOT_MODE.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmSystemTags.BOOT_MODE_TOKEN); cmd.setBootMode(bootMode == null ? ImageBootMode.Legacy.toString() : bootMode);
@Override public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { List<VmNicInventory> nics = inv.getVmNics(); List<L3NetworkVO> l3vos = new ArrayList<>(); return; logger.info(String.format("check and realize vxlan networks[uuid: %s] for vm[uuid: %s] done", vxlanUuids, inv.getUuid())); completion.success(); if (!completion.isSuccess()) { throw new OperationFailureException(operr("cannot configure vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", inv.getUuid(), destHostUuid).causedBy(completion.getErrorCode()));
@Override public void rollback(FlowRollback chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); HostInventory host = spec.getDestHost(); // if ChangeImage, then no need to ReturnHostCapacity, and resume vm info if (spec.getCurrentVmOperation() == VmOperation.ChangeImage) { VmInstanceVO vmvo = dbf.findByUuid(spec.getVmInventory().getUuid(), VmInstanceVO.class); vmvo.setClusterUuid(spec.getVmInventory().getClusterUuid()); vmvo.setLastHostUuid(spec.getVmInventory().getLastHostUuid()); vmvo.setHypervisorType(spec.getVmInventory().getHypervisorType()); dbf.update(vmvo); } else if (host != null) { ReturnHostCapacityMsg msg = new ReturnHostCapacityMsg(); msg.setCpuCapacity(spec.getVmInventory().getCpuNum()); msg.setMemoryCapacity(spec.getVmInventory().getMemorySize()); msg.setHostUuid(host.getUuid()); msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); bus.send(msg); } chain.rollback(); } }
@Override public void afterMigrateVm(final VmInstanceInventory inv, String srcHostUuid) { List<EipTO> eips = getEipsByVmUuid(inv.getUuid()); if (eips == null || eips.isEmpty()) { return; } batchDeleteEips(eips, srcHostUuid, new NopeCompletion()); batchApplyEips(eips, inv.getHostUuid(), new Completion(null) { @Override public void success() { // pass } @Override public void fail(ErrorCode errorCode) { N.New(VmInstanceVO.class, inv.getUuid()).warn_("after migration, failed to apply EIPs[uuids:%s] to the vm[uuid:%s, name:%s] on the destination host[uuid:%s], %s", eips.stream().map(e -> e.vip).collect(Collectors.toList()), inv.getUuid(), inv.getName(), inv.getHostUuid(), errorCode); } }); }
@Override public void run(final FlowTrigger next, Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); final String srcHostUuid = spec.getVmInventory().getHostUuid(); final String dstHostUuid = spec.getDestHost().getUuid(); q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid()); final LocalStorageResourceRefVO ref = q.find(); chain.setName(String.format("migrate-vm-%s-on-localstorage-%s", spec.getVmInventory().getUuid(), ref.getPrimaryStorageUuid())); chain.then(new ShareFlow() { long requiredSize = 0; rootVolume = spec.getVmInventory().getRootVolume(); backend = new LocalStorageKvmBackend(dbf.findByUuid(rootVolume.getPrimaryStorageUuid(), PrimaryStorageVO.class)); String imageUuid = rootVolume.getRootImageUuid();
@Override protected FlowChain getStartVmWorkFlowChain(VmInstanceInventory inv) { FlowChain chain = super.getStartVmWorkFlowChain(inv); chain.setName(String.format("start-appliancevm-%s", inv.getUuid())); chain.insert(new Flow() { String __name__ = "change-appliancevm-status-to-connecting"; prepareFirewallInfo(chain); addBootstrapFlows(chain, HypervisorType.valueOf(inv.getHypervisorType()));
final VmInstanceInventory vm = spec.getVmInventory(); if (!VmInstanceConstant.USER_VM_TYPE.equals(vm.getType())) { trigger.next(); return; final List<VmNicInventory> nicsNeedNewIp = new ArrayList<VmNicInventory>(vm.getVmNics().size()); final List<VmNicInventory> usedIpNics = new ArrayList<VmNicInventory>(); for (VmNicInventory nic : vm.getVmNics()) { if (nic.getUsedIpUuid() == null) { nicsNeedNewIp.add(nic); final Map<String, String> vmStaticIps = new StaticIpOperator().getStaticIpbyVmUuid(vm.getUuid()); List<AllocateIpMsg> amsgs = CollectionUtils.transformToList(nicsNeedNewIp, new Function<AllocateIpMsg, VmNicInventory>() { @Override
@Override public void run(List<MessageReply> replies) { for (MessageReply reply : replies) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); return; } final AllocateIpReply ar = reply.castReply(); final UsedIpInventory ip = ar.getIpInventory(); String nicUuid = CollectionUtils.find(nicsNeedNewIp, new Function<String, VmNicInventory>() { @Override public String call(VmNicInventory arg) { return arg.getL3NetworkUuid().equals(ip.getL3NetworkUuid()) ? arg.getUuid() : null; } }); for (VmNicExtensionPoint ext : pluginRgty.getExtensionList(VmNicExtensionPoint.class)) { ext.afterAddIpAddress(nicUuid, ip.getUuid()); } allocatedIPs.add(UsedIpInventory.valueOf(dbf.findByUuid(ip.getUuid(), UsedIpVO.class))); } VmInstanceVO vmvo = dbf.findByUuid(vm.getUuid(), VmInstanceVO.class); spec.setVmInventory(VmInstanceInventory.valueOf(vmvo)); spec.setDestNics(spec.getVmInventory().getVmNics()); trigger.next(); } });