| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- <?php
- /**
- * The model file of vm module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author xiawenlong <xiawenlong@cnezsoft.com>
- * @package ops
- * @version $Id$
- * @link https://www.zentao.net
- */
- class zanodemodel extends model
- {
- const STATUS_CREATED = 'created';
- const STATUS_LAUNCH = 'launch';
- const STATUS_FAIL_CREATE = 'vm_fail_create';
- const STATUS_RUNNING = 'running';
- const STATUS_SHUTOFF = 'shutoff';
- const STATUS_BUSY = 'busy';
- const STATUS_READY = 'ready';
- const STATUS_UNKNOWN = 'unknown';
- const STATUS_DESTROY = 'destroy';
- const STATUS_RESTORING = 'restoring';
- const STATUS_CREATING_SNAP = 'creating_snap';
- const STATUS_CREATING_IMG = 'creating_img';
- const STATUS_DESTROY_FAIL = 'vim_destroy_fail';
- const KVM_CREATE_PATH = '/api/v1/kvm/create';
- const KVM_TOKEN_PATH = '/api/v1/virtual/getVncToken';
- const KVM_EXPORT_PATH = '/api/v1/kvm/exportVm';
- const KVM_STATUS_PATH = '/api/v1/task/getStatus';
- const SNAPSHOT_CREATE_PATH = '/api/v1/kvm/addCreateSnap';
- const SNAPSHOT_REVERT_PATH = '/api/v1/kvm/addRevertSnap';
- const SNAPSHOT_REMOVE_PATH = '/api/v1/kvm/removeSnap';
- /**
- * 设置语言项。
- * Set lang;
- *
- * @access public
- * @return void
- */
- public function __construct()
- {
- parent::__construct();
- $this->app->lang->host = $this->lang->zanode;
- }
- /**
- * 创建执行节点。
- * Create an Node.
- *
- * @param object $data
- * @access public
- * @return int|bool
- */
- public function create($data)
- {
- $this->dao->insert(TABLE_ZAHOST)->data($data, 'osNamePhysics,osNamePre')->autoCheck()->exec();
- if(dao::isError()) return false;
- $nodeID = $this->dao->lastInsertID();
- $this->loadModel('action')->create('zanode', $nodeID, 'Created');
- return $nodeID;
- }
- /**
- * 通过执行节点创建镜像。
- * Create Image by zanode.
- *
- * @param int $zanodeID
- * @param object $data
- * @access public
- * @return int|bool
- */
- public function createImage($zanodeID, $data)
- {
- $node = $this->getNodeByID($zanodeID);
- if(!$node) return false;
- $newImage = new stdClass();
- $newImage->host = $node->parent;
- $newImage->name = $data->name;
- $newImage->status = 'created';
- $newImage->osName = $node->osName;
- $newImage->from = $node->id;
- $newImage->createdDate = helper::now();
- $this->dao->insert(TABLE_IMAGE)->data($newImage)->autoCheck()->exec();
- if(dao::isError()) return false;
- $newID = $this->dao->lastInsertID();
- /* Prepare create params. */
- $agentUrl = 'http://' . $node->ip . ':' . $node->hzap;
- $param = array(
- 'backing' => $data->name,
- 'task' => $newID,
- 'vm' => $node->name
- );
- $result = json_decode(commonModel::http($agentUrl . static::KVM_EXPORT_PATH, json_encode($param,JSON_NUMERIC_CHECK), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10));
- if(!empty($result) && $result->code == 'success')
- {
- $this->dao->update(TABLE_ZAHOST)->set('status')->eq(static::STATUS_CREATING_IMG)->where('id')->eq($node->id)->exec();
- return $newID;
- }
- $this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($newID)->exec();
- return false;
- }
- /**
- * 创建快照。
- * Create snapshot.
- *
- * @param object $node
- * @param object $snapshot
- * @access public
- * @return false|int
- */
- public function createSnapshot($node, $snapshot)
- {
- $this->dao->insert(TABLE_IMAGE)->data($snapshot)->autoCheck()->exec();
- if(dao::isError()) return false;
- $snapshotID = $this->dao->lastInsertID();
- $agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
- $param = array(array(
- 'name' => $snapshot->name,
- 'task' => $snapshotID,
- 'type' => 'createSnap',
- 'vm' => $node->name
- ));
- $result = json_decode(commonModel::http($agnetUrl . static::SNAPSHOT_CREATE_PATH, json_encode($param,JSON_NUMERIC_CHECK), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10));
- if(!empty($result) && $result->code == 'success')
- {
- $this->loadModel('action')->create('zanode', $node->id, 'createdSnapshot', '', $snapshot->name);
- $this->dao->update(TABLE_ZAHOST)->set('status')->eq(static::STATUS_CREATING_SNAP)->where('id')->eq($node->id)->exec();
- return $snapshotID;
- }
- $this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($snapshotID)->exec();
- dao::$errors = !empty($result) && !empty($result->msg) ? $result->msg : $this->lang->fail;
- return false;
- }
- /**
- * 创建默认的快照。
- * Create default snapshot.
- *
- * @param int $zanodeID
- * @access public
- * @return bool
- */
- public function createDefaultSnapshot($zanodeID = 0)
- {
- $node = $this->getNodeByID($zanodeID);
- if(!$node || $node->status != 'running')
- {
- dao::$errors['name'] = $this->lang->zanode->apiError['notRunning'];
- return false;
- }
- $defaultSnapshot = new stdClass();
- $defaultSnapshot->host = $node->id;
- $defaultSnapshot->name = 'defaultSnap';
- $defaultSnapshot->desc = '';
- $defaultSnapshot->status = 'creating';
- $defaultSnapshot->osName = $node->osName;
- $defaultSnapshot->memory = 0;
- $defaultSnapshot->disk = 0;
- $defaultSnapshot->fileSize = 0;
- $defaultSnapshot->from = 'snapshot';
- $defaultSnapshot->createdBy = 'system';
- $defaultSnapshot->createdDate = helper::now();
- return $this->createSnapshot($node, $defaultSnapshot);
- }
- /**
- * 编辑快照。
- * Edit snapshot.
- *
- * @param int $snapshotID
- * @param object $data
- * @access public
- * @return void
- */
- public function editSnapshot($snapshotID, $data)
- {
- $newSnapshot = new stdClass();
- $newSnapshot->localName = $data->name;
- $newSnapshot->desc = $data->desc;
- $this->dao->update(TABLE_IMAGE)
- ->data($newSnapshot)
- ->where('id')->eq($snapshotID)
- ->autoCheck()
- ->exec();
- }
- /**
- * 将执行节点还原到此快照。
- * Restore zanode to snapshot.
- *
- * @param int $zanodeID
- * @param int $snapshotID
- * @access public
- * @return bool
- */
- public function restoreSnapshot($zanodeID = 0, $snapshotID = 0)
- {
- $node = $this->getNodeByID($zanodeID);
- $snap = $this->getImageByID($snapshotID);
- /* 检查快照的状态。*/
- /* Check snapshot status. */
- $snap->status = $snap->status == 'restoring' && time() - strtotime($snap->restoreDate) > 600 ? 'restore_failed' : $snap->status;
- if(!in_array($snap->status, array('completed', 'restoring', 'restore_failed', 'restore_completed'))) dao::$errors = $this->lang->zanode->snapStatusError;
- if($snap->status == 'restoring') dao::$errors = $this->lang->zanode->snapRestoring;
- if(dao::isError()) return false;
- /* 更新快照状态。*/
- /* Update snapshot status. */
- $this->dao->update(TABLE_IMAGE)->set('status')->eq('restoring')->set('restoreDate')->eq(helper::now())->where('id')->eq($snapshotID)->exec();
- /* 执行还原命令。*/
- /* Execute the restore command. */
- $agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
- $param = array(array(
- 'name' => $snap->name,
- 'task' => $snapshotID,
- 'type' => 'revertSnap',
- 'vm' => $node->name
- ));
- $result = json_decode(commonModel::http($agnetUrl . static::SNAPSHOT_CREATE_PATH, json_encode($param, JSON_NUMERIC_CHECK), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10));
- /* 若执行成功修改执行节点的状态。*/
- /* Change node status when success. */
- if(!empty($result) && $result->code == 'success')
- {
- $this->dao->update(TABLE_ZAHOST)->set('status')->eq('restoring')->where('id')->eq($node->id)->exec();
- $this->loadModel('action')->create('zanode', $zanodeID, 'restoredsnapshot', '', $snap->name);
- return true;
- }
- /* 执行失败时修改快照状态为完成。*/
- /* Change status to completed when fail. */
- $this->dao->update(TABLE_IMAGE)->set('status')->eq('completed')->where('id')->eq($snapshotID)->exec();
- dao::$errors[] = !empty($result) && !empty($result->msg) ? $result->msg : $this->lang->zanode->apiError['fail'];
- return false;
- }
- /**
- * 删除快照。
- * Delete snapshot.
- *
- * @param int $snapshotID
- * @access public
- * @return string|bool
- */
- public function deleteSnapshot($snapshotID)
- {
- $snapshot = $this->getImageByID($snapshotID);
- $node = $this->getNodeByID($snapshot->host);
- $agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
- $param = (object)array(
- 'name' => $snapshot->name,
- 'task' => $snapshotID,
- 'vm' => $node->name
- );
- $result = json_decode(commonModel::http($agnetUrl . static::SNAPSHOT_REMOVE_PATH, json_encode($param,JSON_NUMERIC_CHECK), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10));
- if(!empty($result) && $result->code == 'success')
- {
- $this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($snapshotID)->exec();
- $this->loadModel('action')->create('zanode', $node->id, 'deletesnapshot', '', $snapshot->name);
- return true;
- }
- $error = !empty($result) && !empty($result->msg) ? $result->msg : $this->lang->zanode->apiError['fail'];
- return $error;
- }
- /**
- * 销毁一个执行节点。
- * Destroy Node.
- *
- * @param int $id
- * @access public
- * @return string
- */
- public function destroy($id)
- {
- $node = $this->getNodeByID($id);
- if(!$node) return '';
- if($node->hostType != 'physics')
- {
- $req = array( 'name' => $node->name );
- $agentUrl = 'http://' . $node->ip . ':' . $node->hzap;
- $result = commonModel::http($agentUrl . '/api/v1/kvm/remove', json_encode($req), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10);
- $data = json_decode($result, true);
- if(empty($data)) return $this->lang->zanode->notFoundAgent;
- if($data['code'] != 'success') return zget($this->lang->zanode->apiError, $data['code'], $data['msg']);
- }
- $this->dao->delete()->from(TABLE_ZAHOST)->where('id')->eq($id)->exec();;
- $this->loadModel('action')->create('zanode', $id, 'deleted');
- return '';
- }
- /**
- * 更新一个执行节点。
- * Update Node.
- *
- * @param int $id
- * @param object $hostInfo
- * @return array|bool
- */
- public function update($id, $hostInfo)
- {
- $oldHost = $this->getNodeById($id);
- $this->dao->update(TABLE_ZAHOST)
- ->data($hostInfo)
- ->batchCheck($this->config->zanode->edit->requiredFields, 'notempty')
- ->where('id')->eq($id)
- ->exec();
- if(dao::isError()) return false;
- return common::createChanges($oldHost, $hostInfo);
- }
- /**
- * 更新导出镜像的状态。
- * Update Image status.
- *
- * @param int $imageID
- * @param object $data
- * @access public
- * @return void
- */
- public function updateImageStatus($imageID, $data)
- {
- $this->dao->update(TABLE_IMAGE)->data($data)->where('id')->eq($imageID)->autoCheck()->exec();
- }
- /**
- * 获取执行节点列表。
- * Get zanode list.
- *
- * @param string $browseType
- * @param int $param
- * @param string $orderBy
- * @param object $pager
- * @access public
- * @return array
- */
- public function getListByQuery($browseType = 'all', $param = 0, $orderBy = 't1.id_desc', $pager = null)
- {
- $query = '';
- if($browseType == 'bysearch')
- {
- if($param)
- {
- $query = $this->loadModel('search')->getQuery($param);
- if($query)
- {
- $this->session->set('zanodeQuery', $query->sql);
- $this->session->set('zanodeForm', $query->form);
- }
- else
- {
- $this->session->set('zanodeQuery', ' 1 = 1');
- }
- }
- else
- {
- if($this->session->zanodeQuery == false) $this->session->set('zanodeQuery', ' 1 = 1');
- }
- $query = $this->session->zanodeQuery;
- $query = preg_replace('/`(id|name|status|osName|parent|cpuCores|memory|diskSize|extranet)`/', 't1.`\1`', $query);
- $query = str_replace('`hostID`', 't2.`id`', $query);
- }
- $nodeList = $this->zanodeTao->getZaNodeListByQuery($query, $orderBy, $pager);
- $osList = $this->config->zanode->linuxList + $this->config->zanode->windowsList;
- foreach($nodeList as $node)
- {
- $node = $this->processNodeStatus($node);
- if(isset($osList[$node->osName]) && !empty($osList[$node->osName]))
- {
- $this->dao->update(TABLE_ZAHOST)
- ->beginIF(isset($osList[$node->osName]) && !empty($osList[$node->osName]))->set('osName')->eq($osList[$node->osName])->fi()
- ->where('id')->eq($node->id)
- ->exec();
- }
- }
- return $nodeList;
- }
- /**
- * 获取执行节点的id-name键值对。
- * Get node id-name pairs.
- *
- * @param string $orderBy
- * @access public
- * @return array
- */
- public function getPairs($orderBy = 'id_desc')
- {
- return $this->dao->select('id,name')->from(TABLE_ZAHOST)
- ->where('deleted')->eq(0)
- ->andWhere('type')->in('node,physics')
- ->orderBy($orderBy)
- ->fetchPairs();
- }
- /**
- * 通过宿主机ID获取执行节点。
- * Get node list by hostID
- *
- * @param int $hostID
- * @param string $orderBy
- * @access public
- * @return array
- */
- public function getListByHost($hostID, $orderBy = 'id_desc')
- {
- if(!$hostID) return array();
- $list = $this->zanodeTao->getSubZahostListByID($hostID, $orderBy);
- $host = $this->loadModel('zahost')->getByID($hostID);
- foreach($list as $node)
- {
- $node->heartbeat = empty($node->heartbeat) ? '' : $node->heartbeat;
- if($node->status == 'running' || $node->status == 'ready')
- {
- if(empty($host) || $host->status != 'online')
- {
- $node->status = self::STATUS_SHUTOFF;
- }
- elseif(time() - strtotime($node->heartbeat) > 60)
- {
- $node->status = 'wait';
- }
- }
- }
- return $list;
- }
- /**
- * 通过ID获取host。
- * Get Host by id.
- *
- * @param int $id
- * @access public
- * @return object
- */
- public function getHostByID($id)
- {
- return $this->dao->select('*')->from(TABLE_ZAHOST)
- ->where('id')->eq($id)
- ->fetch();
- }
- /**
- * 通过ip获取host。
- * Get Host by IP.
- *
- * @param string $ip
- * @access public
- * @return object
- */
- public function getHostByIP($ip)
- {
- return $this->dao->select('*')->from(TABLE_ZAHOST)
- ->where('extranet')->eq($ip)
- ->fetch();
- }
- /**
- * 通过 id 获取镜像。
- * Get Image by id.
- *
- * @param int $id
- * @access public
- * @return object|false
- */
- public function getImageByID($id)
- {
- return $this->dao->select('*')->from(TABLE_IMAGE)->where('id')->eq($id)->fetch();
- }
- /**
- * 获取自定义的镜像。
- * Get custom image.
- *
- * @param int $nodeID
- * @param string|array $status
- * @param string $orderBy
- * @access public
- * @return object|false
- */
- public function getCustomImage($nodeID = 0, $status = '', $orderBy = 'id_desc')
- {
- return $this->dao->select('*')->from(TABLE_IMAGE)
- ->where('`from`')->eq($nodeID)
- ->beginIF($status)->andWhere('status')->in($status)->fi()
- ->orderBy($orderBy)
- ->fetch();
- }
- /**
- * 获取快照列表。
- * Get snapshot list.
- *
- * @param int $nodeID
- * @param string $orderBy
- * @param object $pager
- * @access public
- * @return array
- */
- public function getSnapshotList($nodeID, $orderBy = 'id', $pager = null)
- {
- $snapshotList = $this->dao->select('*')->from(TABLE_IMAGE)
- ->where('host')->eq($nodeID)
- ->andWhere('`from`')->eq('snapshot')
- ->orderBy($orderBy)
- ->page($pager)
- ->fetchAll('name');
- foreach($snapshotList as $name => $snapshot)
- {
- if($snapshot->status == 'creating' && (time() - strtotime($snapshot->createdDate)) > 600)
- {
- if($snapshot->name == 'defaultSnap' && $snapshot->createdBy == "system")
- {
- $this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($snapshot->id)->exec();
- $this->dao->update(TABLE_ZAHOST)->data(array("status" => "wait"))->where("id")->eq($snapshot->host)->exec();
- continue;
- }
- $this->dao->update(TABLE_IMAGE)->set('status')->eq('failed')->where('id')->eq($snapshot->id)->exec();
- $snapshotList[$name]->status = 'failed';
- }
- }
- return $snapshotList;
- }
- /**
- * 通过 id 获取执行节点。
- * Get Node by id.
- *
- * @param int $id
- * @access public
- * @return object|false
- */
- public function getNodeByID($id)
- {
- $node = $this->dao->select("t1.*, t2.name as hostName, if(t1.hostType='', t2.extranet, t1.extranet) ip,t2.zap as hzap,if(t1.hostType='', t3.osName, t1.osName) osName, if(t1.hostType='', t2.tokenSN, t1.tokenSN) tokenSN, if(t1.hostType='', t2.secret, t1.secret) secret")
- ->from(TABLE_ZAHOST)->alias('t1')
- ->leftJoin(TABLE_ZAHOST)->alias('t2')->on('t1.parent = t2.id')
- ->leftJoin(TABLE_IMAGE)->alias('t3')->on('t3.id = t1.image')
- ->where('t1.id')->eq($id)
- ->fetch();
- if(empty($node)) return false;
- return $this->processNodeStatus($node);
- }
- /**
- * 通过 mac 地址获取执行节点。
- * Get Node by mac address.
- *
- * @param string $mac
- * @access public
- * @return object|false
- */
- public function getNodeByMac($mac)
- {
- $node = $this->dao->select('*')->from(TABLE_ZAHOST)->where('mac')->eq($mac)->fetch();
- if(empty($node)) return false;
- return $this->processNodeStatus($node);
- }
- /**
- * 计算执行节点的状态。
- * Process node status.
- *
- * @param object $node
- * @access protected
- * @return object
- */
- protected function processNodeStatus($node)
- {
- $oldNodeStatus = $node->status;
- $host = $node->hostType == '' ? $this->loadModel('zahost')->getByID($node->parent) : clone $node;
- if($host && is_object($host))
- {
- $host->status = in_array($host->status, array('running', 'ready')) ? 'online' : $host->status;
- }
- if($node->status == 'running' || $node->status == 'ready' || $node->status == 'online')
- {
- if(empty($host) || $host->status != 'online')
- {
- $node->status = self::STATUS_SHUTOFF;
- }
- elseif(time() - strtotime($node->heartbeat) > 60)
- {
- $node->status = $node->hostType == '' ? 'wait' : 'offline';
- }
- }
- if($node->status == 'creating_img')
- {
- $customImage = $this->getCustomImage($node->id);
- $node->status = !empty($customImage->status) && in_array($customImage->status, array('failed', 'completed')) ? 'running' : $node->status;
- }
- if($oldNodeStatus != $node->status)
- {
- $this->dao->update(TABLE_ZAHOST)->set('status')->eq($node->status)->where('id')->eq($node->id)->exec();
- }
- return $node;
- }
- /**
- * 获取远程操控信息。
- * Get vnc url.
- *
- * @param object $node
- * @access public
- * @return object|bool
- */
- public function getVncUrl($node)
- {
- if($this->loadModel('zahost')->hiddenHost()) return false;
- if(empty($node) || empty($node->parent) || empty($node->vnc)) return false;
- $agnetUrl = 'http://' . $node->ip . ':' . $node->hzap . static::KVM_TOKEN_PATH;
- $result = json_decode(commonModel::http("$agnetUrl?port={$node->vnc}", array(), array(CURLOPT_CUSTOMREQUEST => 'GET'), array("Authorization:$node->tokenSN"), 'json', 'POST', 10));
- if(empty($result) || $result->code != 'success') return false;
- $returnData = new stdClass();
- $returnData->hostIP = $node->ip;
- $returnData->agentPort = $node->hzap;
- $returnData->vnc = $node->vnc;
- $returnData->token = $result->data->token;
- return $returnData;
- }
- /**
- * 通过 product id 获取自动化设置。
- * Get automation by product id.
- *
- * @param int $productID
- * @access public
- * @return object|false
- */
- public function getAutomationByProduct($productID = 0)
- {
- return $this->dao->select('*')->from(TABLE_AUTOMATION)->where('product')->eq($productID)->fetch();
- }
- /**
- * 通过 id 获取自动化设置。
- * Get automation by id.
- *
- * @param int $id
- * @access public
- * @return object|false
- */
- public function getAutomationByID($id)
- {
- return $this->dao->select('*')->from(TABLE_AUTOMATION)->where('id')->eq($id)->fetch();
- }
- /**
- * 自动化设置。
- * Set automation setting.
- *
- * @param object $object
- * @access public
- * @return int|false
- */
- public function setAutomationSetting($object)
- {
- $this->dao->delete()->from(TABLE_AUTOMATION)->where('product')->eq($object->product)->exec();
- $this->dao->insert(TABLE_AUTOMATION)
- ->data($object)
- ->batchCheck('node,scriptPath', 'notempty')
- ->autoCheck()
- ->exec();
- if(dao::isError()) return false;
- return $this->dao->lastInsertID();
- }
- /**
- * 执行ZTF脚本。
- * Run ZTFScript.
- *
- * @param int $scriptID
- * @param int $caseID
- * @param int $testtaskID
- * @access public
- * @return string|object
- */
- public function runZTFScript($scriptID = 0, $caseID = 0, $testtaskID = 0)
- {
- $automation = $this->getAutomationByID($scriptID);
- $node = $this->getNodeByID($automation->node);
- if(empty($node) || $node->status != 'running' || !$node->ip || !$node->ztf || !$node->tokenSN)
- {
- $this->dao->delete()->from(TABLE_TESTRESULT)->where('id')->eq($testtaskID)->exec();
- return dao::$errors = $this->lang->zanode->runTimeout;
- }
- $params = array(
- 'cmd' => $automation->shell,
- 'ids' => strval($caseID),
- 'path' => $automation->scriptPath,
- 'task' => intval($testtaskID)
- );
- $result = json_decode(commonModel::http("http://{$node->ip}:{$node->ztf}/api/v1/jobs/add", json_encode($params), array(), array("Authorization:$node->tokenSN"), 'data', 'POST', 10));
- if(empty($result) || $result->code != 0)
- {
- $this->dao->delete()->from(TABLE_TESTRESULT)->where('id')->eq($testtaskID)->exec();
- return dao::$errors = $this->lang->zanode->runTimeout;
- }
- return $result;
- }
- /**
- * 判断按钮是否可点击。
- * Judge an action is clickable or not.
- *
- * @param object $node
- * @param string $action
- * @access public
- * @return bool
- */
- public static function isClickable($node, $action)
- {
- $action = strtolower($action);
- if(isset($node->from) && $node->from == 'snapshot')
- {
- if(!empty($node->isDefault) && in_array($action, array('editsnapshot', 'deletesnapshot'))) return false;
- }
- if($action == 'resume') return $node->status == 'suspend' && $node->hostType != 'physics';
- if($action == 'start') return $node->status == 'shutoff' && $node->hostType != 'physics';
- if($action == 'getvnc') return $node->hostType == '' && in_array($node->status, array('running', 'launch', 'wait'));
- if($action == 'close' || $action == 'reboot') return $node->hostType != 'physics' && !in_array($node->status, array('wait', 'creating_img', 'creating_snap', 'restoring', 'shutoff'));
- if($action == 'suspend' || $action == 'createsnapshot') return $node->status == 'running' && $node->hostType != 'physics';
- if($action == 'createimage') return ($node->status == 'running' || $node->status == 'creating_img') && $node->hostType != 'physics';
- return true;
- }
- /**
- * 检查创建字段。
- * Check fields of create.
- *
- * @param object $data
- * @access public
- * @return bool
- */
- public function checkFields4Create($data)
- {
- /* 检查必填项。*/
- /* Check required fields. */
- $this->dao->update(TABLE_ZAHOST)->data($data)
- ->batchCheck($this->config->zanode->create->requiredFields, 'notempty');
- if(dao::isError()) return false;
- /* 检查名称格式。*/
- /* Check the style of name. */
- if(!preg_match("/^(?!_)(?!-)(?!\.)[a-zA-Z0-9\_\.\-]+$/", $data->name))
- {
- dao::$errors['name'] = $this->lang->zanode->nameValid;
- return false;
- }
- /* 检查名称的唯一性。*/
- /* If name already exists return error. */
- $node = $this->dao->select('*')->from(TABLE_ZAHOST)->where('name')->eq($data->name)->andWhere('type')->eq('node')->fetch();
- if($node)
- {
- dao::$errors['name'] = $this->lang->zanode->nameUnique;
- return false;
- }
- /* 检查网络状态。*/
- /* Check the status of network. */
- if(!empty($data->hostType) && $data->hostType == 'physics')
- {
- $ping = $this->loadModel('zahost')->checkAddress($data->extranet);
- if(!$ping)
- {
- dao::$errors['extranet'] = $this->lang->zanode->netError;
- return false;
- }
- }
- return true;
- }
- /**
- * 连接Agent服务。
- * Link agent service.
- *
- * @param object $data
- * @access public
- * @return bool
- */
- public function linkAgentService($data)
- {
- $image = $this->getImageByID($data->image);
- $host = $this->getHostByID($data->parent);
- $agentUrl = 'http://' . $host->extranet . ':' . $host->zap;
- $param = array(
- 'os' => $image->osName,
- 'path' => $image->path,
- 'name' => $data->name,
- 'cpu' => (int)$data->cpuCores,
- 'disk' => (int)$data->diskSize,
- 'memory' => (int)$data->memory,
- );
- $result = json_decode(commonModel::http($agentUrl . static::KVM_CREATE_PATH, json_encode($param), array(), array("Authorization:$host->tokenSN"), 'data', 'POST', 10));
- if(empty($result))
- {
- dao::$errors['image'] = $this->lang->zanode->notFoundAgent;
- return false;
- }
- if($result->code != 'success')
- {
- dao::$errors['image'] = $this->lang->zanode->createVmFail;
- return false;
- }
- return $result;
- }
- /**
- * 设置菜单
- * Set menu
- *
- * @access public
- * @return void
- */
- public function setMenu()
- {
- if($this->loadModel('zahost')->hiddenHost())
- {
- unset($this->lang->qa->menu->automation['subMenu']->zahost);
- }
- }
- }
|