protected VmInstanceInventory(VmInstanceVO vo) { this.setUuid(vo.getUuid()); this.setName(vo.getName()); this.setDescription(vo.getDescription()); this.setZoneUuid(vo.getZoneUuid()); this.setClusterUuid(vo.getClusterUuid()); this.setImageUuid(vo.getImageUuid()); this.setHostUuid(vo.getHostUuid()); this.setLastHostUuid(vo.getLastHostUuid()); this.setInstanceOfferingUuid(vo.getInstanceOfferingUuid()); this.setType(vo.getType()); this.setHypervisorType(vo.getHypervisorType()); this.setCreateDate(vo.getCreateDate()); this.setLastOpDate(vo.getLastOpDate()); this.setState(vo.getState().toString()); this.setRootVolumeUuid(vo.getRootVolumeUuid()); this.setAllVolumes(VolumeInventory.valueOf(vo.getAllVolumes())); this.setVmNics(VmNicInventory.valueOf(vo.getVmNics())); this.setVmCdRoms(VmCdRomInventory.valueOf(vo.getVmCdRoms())); this.setInternalId(vo.getInternalId()); this.setDefaultL3NetworkUuid(vo.getDefaultL3NetworkUuid()); this.setCpuNum(vo.getCpuNum()); this.setCpuSpeed(vo.getCpuSpeed()); this.setMemorySize(vo.getMemorySize()); this.setAllocatorStrategy(vo.getAllocatorStrategy()); this.setPlatform(vo.getPlatform()); }
@Override protected void scripts() { self = findByUuid(self.getUuid(), self.getClass()); if (runnable != null) { runnable.run(); } if (state == VmInstanceState.Stopped) { // cleanup the hostUuid if the VM is stopped if (self.getHostUuid() != null) { self.setLastHostUuid(self.getHostUuid()); } self.setHostUuid(null); } self.setState(state); self = merge(self); } };
@Override public void handle(final ErrorCode errCode, Map data) { if (originalCopy.getState() == VmInstanceState.Running) { checkState(originalCopy.getHostUuid(), new NoErrorCompletion(completion) { @Override public void done() { completion.fail(errCode); } }); } else { changeVmStateInDb(VmInstanceStateEvent.unknown); completion.fail(errCode); } } }).start();
protected VmInstanceVO refreshVO(boolean noException) { VmInstanceVO vo = self; self = dbf.findByUuid(self.getUuid(), VmInstanceVO.class); if (self == null && noException) { return null; } if (self == null) { throw new OperationFailureException(operr("vm[uuid:%s, name:%s] has been deleted", vo.getUuid(), vo.getName())); } originalCopy = ObjectUtils.newAndCopy(vo, vo.getClass()); return self; }
@Override public String getName() { return String.format("lock-vm-%s", self.getUuid()); } });
private void handle(final AttachNicToVmMsg msg) { ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); if (allowed != null) { bus.replyErrorByMessageType(msg, allowed); return; } AttachNicToVmOnHypervisorMsg amsg = new AttachNicToVmOnHypervisorMsg(); amsg.setVmUuid(self.getUuid()); amsg.setHostUuid(self.getHostUuid()); amsg.setNics(msg.getNics()); bus.makeTargetServiceIdByResourceUuid(amsg, HostConstant.SERVICE_ID, self.getHostUuid()); bus.send(amsg, new CloudBusCallBack(msg) { @Override public void run(MessageReply reply) { if (self.getDefaultL3NetworkUuid() == null) { self.setDefaultL3NetworkUuid(msg.getNics().get(0).getL3NetworkUuid()); self = dbf.updateAndRefresh(self); logger.debug(String.format("set the VM[uuid: %s]'s default L3 network[uuid:%s], as it doen't have one before", self.getUuid(), self.getDefaultL3NetworkUuid())); } AttachNicToVmReply r = new AttachNicToVmReply(); if (!reply.isSuccess()) { r.setError(err(VmErrors.ATTACH_NETWORK_ERROR, r.getError(), r.getError().getDetails())); } bus.reply(msg, r); } }); }
private void changeCpuAndMemory(final int cpuNum, final long memorySize, final Completion completion) { if (self.getState() == VmInstanceState.Stopped) { self.setCpuNum(cpuNum); self.setMemorySize(memorySize); self = dbf.updateAndRefresh(self); completion.success(); final int oldCpuNum = self.getCpuNum(); final long oldMemorySize = self.getMemorySize(); chain.setName(String.format("change-cpu-and-memory-of-vm-%s", self.getUuid())); chain.then(new NoRollbackFlow() { String __name__ = "align-memory"; String __name__ = String.format("allocate-host-capacity-on-host-%s", self.getHostUuid()); boolean result = false; String __name__ = String.format("change-cpu-of-vm-%s", self.getUuid()); String __name__ = String.format("change-memory-of-vm-%s", self.getUuid());
@Override public void run(VmStateChangedExtensionPoint ext) { ext.vmStateChanged(inv, bs, self.getState()); } });
private VmInstanceDeletionPolicy getVmDeletionPolicy(final VmInstanceDeletionMsg msg) { if (self.getState() == VmInstanceState.Created) { return VmInstanceDeletionPolicy.DBOnly; } return msg.getDeletionPolicy() == null ? deletionPolicyMgr.getDeletionPolicy(self.getUuid()) : VmInstanceDeletionPolicy.valueOf(msg.getDeletionPolicy()); }
@Transactional(readOnly = true) private List<VolumeVO> getAttachableVolume(String accountUuid) { if (!self.getState().equals(VmInstanceState.Stopped) && self.getPlatform().equals(ImagePlatform.Other.toString())) { return Collections.emptyList(); List<String> formats = VolumeFormat.getVolumeFormatSupportedByHypervisorTypeInString(self.getHypervisorType()); if (formats.isEmpty()) { throw new CloudRuntimeException(String.format("cannot find volume formats for the hypervisor type[%s]", self.getHypervisorType())); if (self.getClusterUuid() == null) { " group by cls.uuid"; List<String> clusterUuids = SQL.New(sql) .param("vmUuid", self.getUuid()) .param("clsState", ClusterState.Enabled) .list(); q.setParameter("volStatus", VolumeStatus.Ready); q.setParameter("formats", formats); q.setParameter("vmUuid", self.getUuid()); q.setParameter("type", VolumeType.Data); vos = q.getResultList(); if (self.getClusterUuid() == null) { q.setParameter("volState", VolumeState.Enabled); q.setParameter("volStatus", VolumeStatus.Ready); q.setParameter("vmUuid", self.getUuid()); q.setParameter("formats", formats);
protected void startVm(final Message msg, final Completion completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), null); if (allowed != null) { completion.fail(allowed); if (self.getState() == VmInstanceState.Created) { InstantiateVmFromNewCreatedStruct struct = new JsonLabel().get( InstantiateVmFromNewCreatedStruct.makeLabelKey(self.getUuid()), InstantiateVmFromNewCreatedStruct.class); spec.setRequiredClusterUuid(amsg.getClusterUuid()); spec.setRequiredHostUuid(amsg.getHostUuid()); spec.setUsbRedirect(VmSystemTags.USB_REDIRECT.getTokenByResourceUuid(self.getUuid(), VmSystemTags.USB_REDIRECT_TOKEN)); spec.setEnableRDP(VmSystemTags.RDP_ENABLE.getTokenByResourceUuid(self.getUuid(), VmSystemTags.RDP_ENABLE_TOKEN)); spec.setVDIMonitorNumber(VmSystemTags.VDI_MONITOR_NUMBER.getTokenByResourceUuid(self.getUuid(), VmSystemTags.VDI_MONITOR_NUMBER_TOKEN)); " It doesn't have any nic, please attach a nic and try again", self.getUuid())); final VmInstanceState originState = self.getState(); changeVmStateInDb(VmInstanceStateEvent.starting); setFlowMarshaller(chain); String recentHostUuid = self.getHostUuid() == null ? self.getLastHostUuid() : self.getHostUuid(); String vmHostUuid = self.getHostUuid(); String vmLastHostUuid = self.getLastHostUuid(); chain.setName(String.format("start-vm-%s", self.getUuid())); chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); chain.done(new FlowDoneHandler(completion) {
if (msg.isCheckStatus() && getSelf().getState() != VmInstanceState.Running) { throw new OperationFailureException(operr("the virtual router[name:%s, uuid:%s, current state:%s] is not running," + "and cannot perform required operation. Please retry your operation later once it is running", self.getName(), self.getUuid(), self.getState())); self.getUuid(), getSelf().getStatus(), msg.getPath())); self.getUuid(), msg.getPath()));
private void getStartingCandidateHosts(final NeedReplyMessage msg, final ReturnValueCompletion completion) { refreshVO(); ErrorCode err = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); if (err != null) { throw new OperationFailureException(err); } final DesignatedAllocateHostMsg amsg = new DesignatedAllocateHostMsg(); amsg.setCpuCapacity(self.getCpuNum()); amsg.setMemoryCapacity(self.getMemorySize()); amsg.setVmInstance(VmInstanceInventory.valueOf(self)); amsg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); amsg.setAllocatorStrategy(self.getAllocatorStrategy()); amsg.setVmOperation(VmOperation.Start.toString()); if (self.getImageUuid() != null && dbf.findByUuid(self.getImageUuid(), ImageVO.class) != null) { amsg.setImage(ImageInventory.valueOf(dbf.findByUuid(self.getImageUuid(), ImageVO.class))); } amsg.setL3NetworkUuids(VmNicHelper.getL3Uuids(VmNicInventory.valueOf(self.getVmNics()))); amsg.setDryRun(true); amsg.setListAllHosts(true); bus.send(amsg, new CloudBusCallBack(completion) { @Override public void run(MessageReply re) { if (!re.isSuccess()) { completion.fail(re.getError()); } else { completion.success(re); } } }); }
@Override protected void scripts() { VmInstanceVO vo = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find(); InstanceOfferingVO instanceOfferingVO = Q.New(InstanceOfferingVO.class).eq(InstanceOfferingVO_.uuid, msg.getInstanceOfferingUuid()).find(); if (!VmGlobalConfig.NUMA.value(Boolean.class) && !VmInstanceState.Stopped.equals(vo.getState())) { throw new ApiMessageInterceptionException(argerr( "the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again" )); } if (!VmInstanceState.Stopped.equals(vo.getState()) && !VmInstanceState.Running.equals(vo.getState())) { throw new OperationFailureException(operr("The state of vm[uuid:%s] is %s. Only these state[%s] is allowed to update cpu or memory.", vo.getUuid(), vo.getState(), StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ","))); } if (VmInstanceState.Stopped.equals(vo.getState())) { return; } if (instanceOfferingVO.getCpuNum() < vo.getCpuNum() || instanceOfferingVO.getMemorySize() < vo.getMemorySize()) { throw new ApiMessageInterceptionException(argerr( "can't decrease capacity when vm[uuid:%s] is running", vo.getUuid() )); } } }.execute();
@Override public void success() { extEmitter.afterDestroyVm(inv); logger.debug(String.format("successfully deleted vm instance[name:%s, uuid:%s]", self.getName(), self.getUuid())); if (deletionPolicy == VmInstanceDeletionPolicy.Direct) { changeVmStateInDb(VmInstanceStateEvent.destroyed); callVmJustBeforeDeleteFromDbExtensionPoint(); dbf.removeCollection(self.getVmCdRoms(), VmCdRomVO.class); dbf.remove(getSelf()); } else if (deletionPolicy == VmInstanceDeletionPolicy.DBOnly || deletionPolicy == VmInstanceDeletionPolicy.KeepVolume) { changeVmStateInDb(VmInstanceStateEvent.destroyed, ()-> self.setHostUuid(null)); } else if (deletionPolicy == VmInstanceDeletionPolicy.Never) { logger.warn(String.format("the vm[uuid:%s] is deleted, but by it's deletion policy[Never]," + " the root volume is not deleted on the primary storage", self.getUuid())); changeVmStateInDb(VmInstanceStateEvent.destroyed, ()-> self.setHostUuid(null));
private void getVmMigrationTargetHost(Message msg, final ReturnValueCompletion<List<HostInventory>> completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), VmErrors.MIGRATE_ERROR); if (allowed != null) { completion.fail(allowed); amsg.setCpuCapacity(self.getCpuNum()); amsg.setMemoryCapacity(self.getMemorySize()); amsg.getAvoidHostUuids().add(self.getHostUuid()); if (msg instanceof GetVmMigrationTargetHostMsg) { GetVmMigrationTargetHostMsg gmsg = (GetVmMigrationTargetHostMsg) msg; amsg.setAllocatorStrategy(HostAllocatorConstant.MIGRATE_VM_ALLOCATOR_TYPE); amsg.setVmOperation(VmOperation.Migrate.toString()); amsg.setL3NetworkUuids(VmNicHelper.getL3Uuids(VmNicInventory.valueOf(self.getVmNics()))); amsg.setDryRun(true); amsg.setAllowNoL3Networks(true);
if (expected != self.getState()) { bus.reply(msg, reply); completion.done(); final String originalHostUuid = self.getHostUuid(); final String currentHostUuid = msg.getHostUuid(); final VmInstanceState originalState = self.getState(); final VmInstanceState currentState = VmInstanceState.valueOf(msg.getStateOnHost()); self.getUuid(), originalState, originalHostUuid)); bus.reply(msg, reply); completion.done(); data.setVmUuid(self.getUuid()); data.setFrom(originalState); data.setTo(self.getState()); data.setOriginalHostUuid(originalHostUuid); data.setCurrentHostUuid(self.getHostUuid()); evtf.fire(VmTracerCanonicalEvents.VM_STATE_CHANGED_PATH, data); }; changeVmStateInDb(VmInstanceStateEvent.running, ()-> self.setHostUuid(msg.getHostUuid())); fireEvent.run(); bus.reply(msg, reply); changeVmStateInDb(VmInstanceStateEvent.stopped, ()-> self.setHostUuid(null)); fireEvent.run(); bus.reply(msg, reply);
private void detachNic(final String nicUuid, boolean releaseNic, final Completion completion) { VmNicVO vmNicVO = CollectionUtils.find(self.getVmNics(), new Function<VmNicVO, VmNicVO>() { @Override public VmNicVO call(VmNicVO arg) { CollectionUtils.find(self.getVmNics(), new Function<VmNicVO, VmNicVO>() { @Override public VmNicVO call(VmNicVO arg) { flowChain.setName(String.format("detachNic-vm-%s-nic-%s", self.getUuid(), nicUuid)); setFlowMarshaller(flowChain); flowChain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); flowChain.getData().put(Params.ReleaseNicAfterDetachNic.toString(), releaseNic); if (self.getState() == VmInstanceState.Running) { flowChain.then(new VmDetachNicOnHypervisorFlow());
protected void selectDefaultL3(VmNicInventory nic) { if (self.getDefaultL3NetworkUuid() != null && !VmNicHelper.isDefaultNic(nic, VmInstanceInventory.valueOf(self))) { return; final VmNicVO candidate = CollectionUtils.find(self.getVmNics(), new Function<VmNicVO, VmNicVO>() { @Override public VmNicVO call(VmNicVO arg) { self.setDefaultL3NetworkUuid(newDefaultL3); logger.debug(String.format( "after detaching the nic[uuid:%s, L3 uuid:%s], change the default L3 of the VM[uuid:%s]" + " to the L3 network[uuid: %s]", nic.getUuid(), VmNicHelper.getL3Uuids(nic), self.getUuid(), newDefaultL3)); } else { self.setDefaultL3NetworkUuid(null); logger.debug(String.format( "after detaching the nic[uuid:%s, L3 uuid:%s], change the default L3 of the VM[uuid:%s]" + " to null, as the VM has no other nics", nic.getUuid(), VmNicHelper.getL3Uuids(nic), self.getUuid()));
@Override public void handle(Map data) { CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmAfterExpungeExtensionPoint.class), arg -> arg.vmAfterExpunge(inv)); callVmJustBeforeDeleteFromDbExtensionPoint(); dbf.reload(self); dbf.removeCollection(self.getVmNics(), VmNicVO.class); dbf.removeCollection(self.getVmCdRoms(), VmCdRomVO.class); dbf.remove(self); logger.debug(String.format("successfully expunged the vm[uuid:%s]", self.getUuid())); dbf.eoCleanup(VmInstanceVO.class, Collections.singletonList(self.getUuid())); completion.success(); } }).error(new FlowErrorHandler(completion) {