void Task_VzStateMonitor::processRegisterEvt(const QString &ctid) { PRL_RESULT res; SmartPtr<CVmConfiguration> pConfig = CDspService::instance()->getVzHelper()-> getVzlibHelper().get_env_config_by_ctid(ctid); if (!pConfig) return; QString vm_uuid = pConfig->getVmIdentification()->getVmUuid(); QString vm_name = pConfig->getVmIdentification()->getVmName(); QString vm_home = pConfig->getVmIdentification()->getHomePath(); WRITE_TRACE(DBG_INFO, "Register Ct uuid=%s name=%s home=%s", QSTR2UTF8(vm_uuid), QSTR2UTF8(vm_name), QSTR2UTF8(vm_home)); CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name); res = CDspService::instance()->getVmDirManager() .checkAndLockNotExistsExclusiveVmParameters(QStringList(), &vmInfo); if (PRL_FAILED(res)) return; CDspService::instance()->getVzHelper()->insertVmDirectoryItem(pConfig); // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(&vmInfo); }
PRL_RESULT Task_VzManager::delete_env() { PRL_RESULT res, ret; CProtoCommandPtr pCmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if (!pCmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; CProtoVmDeleteCommand * pDeleteCmd = CProtoSerializer::CastToProtoCommand<CProtoVmDeleteCommand>(pCmd); QString sUuid = pDeleteCmd->GetVmUuid(); VIRTUAL_MACHINE_STATE nState; res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState); if (PRL_FAILED(res)) return res; if (nState == VMS_MOUNTED) { res = get_op_helper()->umount_env(sUuid); if (PRL_FAILED(res)) return res; } res = check_env_state(PVE::DspCmdDirVmDelete, sUuid); if (PRL_FAILED(res)) return res; SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (!pConfig) return PRL_ERR_VM_GET_CONFIG_FAILED; QString vm_uuid = pConfig->getVmIdentification()->getVmUuid(); QString vm_name = pConfig->getVmIdentification()->getVmName(); QString vm_home = pConfig->getVmIdentification()->getHomePath(); CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name); res = CDspService::instance()->getVmDirManager() .lockExclusiveVmParameters(m_sVzDirUuid, &vmInfo); if (PRL_SUCCEEDED(res)) { Backup::Device::Service(pConfig).teardown(); res = get_op_helper()->delete_env(sUuid); if (PRL_SUCCEEDED(res)) { // FIXME: rollback operation ret = CDspService::instance()->getVmDirHelper() .deleteVmDirectoryItem(m_sVzDirUuid, vm_uuid); if (PRL_FAILED(ret) && ret != PRL_ERR_ENTRY_DOES_NOT_EXIST) WRITE_TRACE(DBG_FATAL, "Can't delete Container %s from VmDirectory by error: %s", QSTR2UTF8(vm_uuid), PRL_RESULT_TO_STRING(ret) ); } // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(m_sVzDirUuid, &vmInfo); } return res; }
PRL_RESULT Task_VzManager::register_env() { CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if ( ! cmd->IsValid() ) return PRL_ERR_UNRECOGNIZED_REQUEST; QString sPath = cmd->GetFirstStrParam(); if (!QFileInfo(sPath).exists()) { getLastError()->addEventParameter(new CVmEventParameter( PVE::String, sPath, EVT_PARAM_MESSAGE_PARAM_0 )); return PRL_ERR_DIRECTORY_DOES_NOT_EXIST; } SmartPtr<CVmConfiguration> pConfig; QString sUuid = cmd->GetVmUuid(); if (cmd->GetCommandFlags() & PRVF_REGENERATE_VM_UUID) sUuid = Uuid::createUuid().toString(); QString vm_uuid = sUuid; QString vm_name; QString vm_home = sPath + "/" + VMDIR_DEFAULT_VM_CONFIG_FILE; PRL_RESULT res; CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name); // Lock res = checkAndLockRegisterParameters(&vmInfo); if (PRL_FAILED(res)) return res; res = get_op_helper()->register_env(sPath, QString(), sUuid, cmd->GetCommandFlags(), pConfig); if (PRL_SUCCEEDED(res)) { res = getVzHelper()->insertVmDirectoryItem(pConfig); if (PRL_FAILED(res)) get_op_helper()->unregister_env( pConfig->getVmIdentification()->getVmUuid(), 0); } // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(&vmInfo); if (PRL_SUCCEEDED(res)) getResponseCmd()->SetVmConfig(pConfig->toString()); return res; }
PRL_RESULT Task_VzManager::create_env() { CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage()); if ( ! cmd->IsValid() ) return PRL_ERR_UNRECOGNIZED_REQUEST; CProtoVmCreateCommand *pCmd = CProtoSerializer::CastToProtoCommand<CProtoVmCreateCommand>(cmd); if (!pCmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; SmartPtr<CVmConfiguration> pConfig(new CVmConfiguration); pConfig->fromString(pCmd->GetVmConfig()); QString sPath = pCmd->GetVmHomePath(); if (!sPath.isEmpty() && !QDir::isAbsolutePath( sPath) ) { WRITE_TRACE(DBG_FATAL, "Invalid path '%s'", QSTR2UTF8(sPath)); return PRL_ERR_VMDIR_PATH_IS_NOT_ABSOLUTE; } QString vm_uuid = pConfig->getVmIdentification()->getVmUuid(); QString vm_name = pConfig->getVmIdentification()->getVmName(); QString vm_home; CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name); // Lock PRL_RESULT res = checkAndLockRegisterParameters(&vmInfo); if (PRL_FAILED(res)) return res; res = get_op_helper()->create_env(sPath, pConfig, pCmd->GetCommandFlags()); if (PRL_SUCCEEDED(res)) { res = getVzHelper()->insertVmDirectoryItem(pConfig); if (PRL_FAILED(res)) get_op_helper()->delete_env( pConfig->getVmIdentification()->getVmUuid()); } // Unlock temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(&vmInfo); if (PRL_SUCCEEDED(res)) { getResponseCmd()->SetVmConfig(pConfig->toString()); sendEvent(PET_DSP_EVT_VM_ADDED, vm_uuid); } return res; }
PRL_RESULT Task_VzManager::unregister_env() { PRL_RESULT res, ret; CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if ( ! cmd->IsValid() ) return PRL_ERR_UNRECOGNIZED_REQUEST; QString uuid = cmd->GetVmUuid(); // Check state res = check_env_state(PVE::DspCmdDirUnregVm, uuid); if (PRL_FAILED(res)) return res; SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), uuid); if (!pConfig) return PRL_ERR_VM_GET_CONFIG_FAILED; QString vm_name = pConfig->getVmIdentification()->getVmName(); QString vm_home = pConfig->getVmIdentification()->getHomePath(); // Lock by vm_uuid/vm_name/vm_home triade CVmDirectory::TemporaryCatalogueItem vmInfo(uuid, vm_home, vm_name); res = CDspService::instance()->getVmDirManager() .lockExclusiveVmParameters(m_sVzDirUuid, &vmInfo); if (PRL_SUCCEEDED(res)) { res = get_op_helper()->unregister_env(uuid, 0); if (PRL_SUCCEEDED(res)) { Backup::Device::Service(pConfig).disable(); ret = CDspService::instance()->getVmDirHelper() .deleteVmDirectoryItem(m_sVzDirUuid, uuid); if (PRL_FAILED(ret) && ret != PRL_ERR_ENTRY_DOES_NOT_EXIST) WRITE_TRACE(DBG_FATAL, "Can't delete Container %s from VmDirectory by error: %s", QSTR2UTF8(uuid), PRL_RESULT_TO_STRING(ret) ); } // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(m_sVzDirUuid, &vmInfo); } return res; }
PRL_RESULT Task_VzManager::clone_env() { PRL_RESULT res; CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if (!cmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; CProtoVmCloneCommand *pCmd = CProtoSerializer::CastToProtoCommand<CProtoVmCloneCommand>(cmd); QString sUuid = pCmd->GetVmUuid(); QString sNewHome = pCmd->GetVmHomePath(); QString sNewName = pCmd->GetVmName(); unsigned int nFlags = pCmd->GetCommandFlags(); if (sNewName.isEmpty()) return PRL_ERR_VM_NAME_IS_EMPTY; res = check_env_state(PVE::DspCmdDirVmClone, sUuid); if (PRL_FAILED(res)) return res; SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (!pConfig) { WRITE_TRACE(DBG_FATAL, "Unable to find CT by uuid %s", QSTR2UTF8(sUuid)); return PRL_ERR_VM_GET_CONFIG_FAILED; } SmartPtr<CVmConfiguration> pNewConfig(new CVmConfiguration); if (!pCmd->GetNewVmUuid().isEmpty()) pNewConfig->getVmIdentification()->setVmUuid(pCmd->GetNewVmUuid()); CVmDirectory::TemporaryCatalogueItem vmInfo( pNewConfig->getVmIdentification()->getVmUuid(), QString(), sNewName); res = checkAndLockRegisterParameters(&vmInfo); if (PRL_FAILED(res)) return res; res = get_op_helper()->clone_env(pConfig, sNewHome, sNewName, nFlags, pNewConfig); if (PRL_SUCCEEDED(res)) { res = getVzHelper()->insertVmDirectoryItem(pNewConfig); if (PRL_FAILED(res)) get_op_helper()->delete_env( pNewConfig->getVmIdentification()->getVmUuid()); } // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(&vmInfo); if (PRL_FAILED(res) || !pNewConfig.isValid()) return res; SmartPtr<CVmConfiguration> pOldConfig(new CVmConfiguration(pNewConfig->toString())); bool isTemplate = (nFlags & PCVF_CLONE_TO_TEMPLATE); pNewConfig->getVmSettings()->getVmCommonOptions()->setTemplate(isTemplate); Task_CloneVm::ResetNetSettings(pNewConfig); Backup::Device::Dao(pNewConfig).deleteAll(); get_op_helper()->apply_env_config(pNewConfig, pOldConfig, PVCF_DESTROY_HDD_BUNDLE); getResponseCmd()->SetVmConfig(pNewConfig->toString()); { CVmEvent event(PET_DSP_EVT_VM_ADDED, pNewConfig->getVmIdentification()->getVmUuid(), PIE_DISPATCHER); SmartPtr<IOPackage> p = DispatcherPackage::createInstance(PVE::DspVmEvent, event); CDspService::instance()->getClientManager().sendPackageToAllClients(p); } // Set some parameters in the response (see Task_CloneVm) CDspLockedPointer<CVmEvent> pParams = getTaskParameters(); pParams->addEventParameter( new CVmEventParameter( PVE::String, pNewConfig->getVmIdentification()->getVmUuid(), EVT_PARAM_DISP_TASK_CLONE_VM_UUID ) ); pParams->addEventParameter( new CVmEventParameter( PVE::String, pNewConfig->getVmIdentification()->getVmName(), EVT_PARAM_DISP_TASK_CLONE_NEW_VM_NAME ) ); pParams->addEventParameter( new CVmEventParameter( PVE::String, pNewConfig->getVmIdentification()->getHomePath(), EVT_PARAM_DISP_TASK_CLONE_NEW_VM_ROOT_DIR ) ); pParams->addEventParameter( new CVmEventParameter( PVE::Boolean, QString("%1").arg(isTemplate), EVT_PARAM_DISP_TASK_CLONE_AS_TEMPLATE ) ); return PRL_ERR_SUCCESS; }
PRL_RESULT Task_VzManager::editConfig() { PRL_RESULT res; CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if ( ! cmd->IsValid() ) return PRL_ERR_UNRECOGNIZED_REQUEST; SmartPtr<CVmConfiguration> pConfig( new CVmConfiguration( cmd->GetFirstStrParam() ) ); if( !IS_OPERATION_SUCCEEDED( pConfig->m_uiRcInit ) ) { PRL_RESULT code = PRL_ERR_PARSE_VM_CONFIG; WRITE_TRACE(DBG_FATAL, "Error occurred while modification CT configuration: %s", PRL_RESULT_TO_STRING( code ) ); return code; } QString sUuid = pConfig->getVmIdentification()->getVmUuid(); SmartPtr<CVmConfiguration> pOldConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (!pOldConfig) return PRL_ERR_VM_GET_CONFIG_FAILED; QString oldname = pOldConfig->getVmIdentification()->getVmName(); QString name = pConfig->getVmIdentification()->getVmName(); QStringList lstFullItemIds; pConfig->diffDocuments(pOldConfig.getImpl(), lstFullItemIds); // Code below prohibits all other than Hdd and Network devices for Containers if (!lstFullItemIds.filter(QRegExp("Hardware\\.(?!Hdd|Network|Cpu|Memory)")).isEmpty()) return PRL_ERR_ACTION_NOT_SUPPORTED_FOR_CT; // Handle the Firewall settings change on the running CT if (!lstFullItemIds.filter(QRegExp("\\.(?=Firewall\\.|MAC|NetAddress)")).isEmpty()) { VIRTUAL_MACHINE_STATE nState = VMS_UNKNOWN; PRL_RESULT res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState); if (nState == VMS_RUNNING) { res = setupFirewall(pConfig); if (PRL_FAILED(res)) return res; } } // Handle Name change if (oldname != name) { QString vm_uuid; // Skip uuid check QString vm_name = name; QString vm_home; // Lock the new name in the VmDirectory CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name); res = checkAndLockRegisterParameters(&vmInfo); if (PRL_FAILED(res)) return res; res = get_op_helper()->set_env_name(sUuid, name); if (PRL_SUCCEEDED(res)) { CDspLockedPointer< CVmDirectoryItem > pVmDirItem = CDspService::instance()->getVmDirManager() .getVmDirItemByUuid(m_sVzDirUuid, sUuid ); if (!pVmDirItem) { WRITE_TRACE(DBG_FATAL, "Can't found VmDirItem by vmUuid = %s", QSTR2UTF8(sUuid)); } else { pVmDirItem->setVmName(name); PRL_RESULT ret = CDspService::instance()->getVmDirManager().updateVmDirItem(pVmDirItem); if (PRL_FAILED(ret) ) WRITE_TRACE(DBG_FATAL, "Can't update Container %s VmCatalogue by error: %s", QSTR2UTF8(sUuid), PRL_RESULT_TO_STRING(ret)); } } // delete temporary registration CDspService::instance()->getVmDirManager() .unlockExclusiveVmParameters(&vmInfo); if (PRL_FAILED(res)) return res; } // reset IP addresses for CT templates Task_EditVm::resetNetworkAddressesFromVmConfig(pConfig, pOldConfig); // update High Availability Cluster resource if (pConfig->getVmSettings()->getHighAvailability()->toString() != pOldConfig->getVmSettings()->getHighAvailability()->toString() && CFileHelper::isSharedFS(pConfig->getVmIdentification()->getHomePath())) { res = CDspService::instance()->getHaClusterHelper()->updateClusterResourceParams( sUuid, pOldConfig->getVmSettings()->getHighAvailability(), pConfig->getVmSettings()->getHighAvailability(), pConfig->getVmIdentification()->getHomePath(), PVT_CT); if (PRL_FAILED(res)) return res; } CVmRemoteDisplay* oldD = pOldConfig->getVmSettings()->getVmRemoteDisplay(); CVmRemoteDisplay* newD = pConfig->getVmSettings()->getVmRemoteDisplay(); if (oldD->getPassword() != newD->getPassword()) { if (newD->getPassword().length() > PRL_VM_REMOTE_DISPLAY_MAX_PASS_LEN) { WRITE_TRACE(DBG_FATAL, "The specified remote display password is too long."); getLastError()->addEventParameter( new CVmEventParameter( PVE::UnsignedInt, QString::number(PRL_VM_REMOTE_DISPLAY_MAX_PASS_LEN), EVT_PARAM_MESSAGE_PARAM_0)); return PRL_ERR_VMCONF_REMOTE_DISPLAY_PASSWORD_TOO_LONG; } } Backup::Device::Service service(pOldConfig); service.setContext(*this).setVmHome(pConfig->getVmIdentification()->getHomePath()); Backup::Device::Details::Transition t = service.getTransition(pConfig); res = t.plant(); if (PRL_FAILED(res)) return res; res = get_op_helper()->apply_env_config(pConfig, pOldConfig, cmd->GetCommandFlags()); if (PRL_FAILED(res)) return res; res = t.remove(); if (PRL_FAILED(res)) return res; // Invalidate cache CDspService::instance()->getVzHelper()->getConfigCache(). remove(pConfig->getVmIdentification()->getHomePath()); res = changeVNCServerState(pOldConfig, pConfig, sUuid); if (PRL_FAILED(res)) return res; // Handle memory limit change unsigned int newRamSize = pConfig->getVmHardwareList()->getMemory()->getRamSize(); unsigned int oldRamSize = pOldConfig->getVmHardwareList()->getMemory()->getRamSize(); if (newRamSize != oldRamSize) { VIRTUAL_MACHINE_STATE nState = VMS_UNKNOWN; PRL_RESULT res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState); if (PRL_SUCCEEDED(res) && (nState == VMS_RUNNING)) adjustReservedMemLimit((long long)newRamSize - oldRamSize); } QStringList lstAdd, lstDel; // Handle application templates QStringList newAppTemplates = pConfig->getCtSettings()->getAppTemplate(); QStringList oldAppTemplates = pOldConfig->getCtSettings()->getAppTemplate(); for (int i = 0; i < newAppTemplates.size(); i++) { if (newAppTemplates.at(i).startsWith('.')) newAppTemplates[i].remove(0, 1); } for (int i = 0; i < oldAppTemplates.size(); i++) { if (oldAppTemplates.at(i).startsWith('.')) oldAppTemplates[i].remove(0, 1); } if (newAppTemplates == oldAppTemplates) goto ok; foreach(QString str, newAppTemplates) if (!oldAppTemplates.contains(str)) lstAdd.append(str); foreach(QString str, oldAppTemplates) if (!newAppTemplates.contains(str)) lstDel.append(str); do { CVzTemplateHelper TmplHelper = getVzHelper()->getVzTemplateHelper(); res = TmplHelper.remove_templates_env(sUuid, lstDel); if (PRL_FAILED(res)) return res; res = TmplHelper.install_templates_env(sUuid, lstAdd); } while (0); ok: if ( PRL_SUCCEEDED(res) ) { SmartPtr<CVmConfiguration> pNewConfig = getVzHelper()->getCtConfig(getClient(), sUuid); QStringList lstParams(pNewConfig ? pNewConfig->toString() : pConfig->toString()); getResponseCmd()->SetParamsList( lstParams ); sendEvent(PET_DSP_EVT_VM_CONFIG_CHANGED, sUuid); } return res; }