Merge branch 'zenops_61' into 'master'

Zenops 61

See merge request easycorp/zentaopms!6876
This commit is contained in:
王怡栋
2023-02-08 01:55:38 +00:00
33 changed files with 751 additions and 60 deletions
+3
View File
@@ -78,6 +78,9 @@ class hostHeartbeatEntry extends baseEntry
'status' => $vm->status,
'extranet' => $vm->ip,
);
if(!$vm->sshPortOnHost) unset($vmData['ssh']);
if($heartbeat > 0) $vmData['heartbeat'] = date("Y-m-d H:i:s", $heartbeat);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
+11 -2
View File
@@ -23,7 +23,7 @@ class hostSubmitEntry extends baseEntry
/* Check authorize. */
$header = getallheaders();
$token = isset($header['Authorization']) ? substr($header['Authorization'], 7) : '';
// if(!$token) return $this->sendError(401, 'Unauthorized');
if(!$token) return $this->sendError(401, 'Unauthorized');
$now = helper::now();
@@ -38,7 +38,16 @@ class hostSubmitEntry extends baseEntry
->andWhere('tokenTime')->gt($now)->fi()
->fetch('id');
// if(!$id) return $this->sendError(400, 'Secret error.');
if(!$id) return $this->sendError(400, 'Secret error.');
$imageInfo = $this->dao->select('`status`,`from`')->from(TABLE_IMAGE)
->where('id')->eq($task)
->fetch();
if(empty($imageInfo)) return $this->sendSuccess(200, 'success');
if($imageInfo->from == 'snapshot' && $imageInfo->status == 'restoring')
{
$image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
}
$this->dao->update(TABLE_IMAGE)->data($image)->where("id")->eq($task)->exec();
+1 -1
View File
@@ -227,7 +227,7 @@ $config->openMethods[] = 'doc.createbasicinfo';
$config->openMethods[] = 'project.createguide';
$config->openMethods[] = 'task.editteam';
$config->openMethods[] = 'feedback.mergeproductmodule';
$config->openMethods[] = 'zahost.introduction';
$config->openMethods[] = 'zanode.list';
$config->openModules = array();
$config->openModules[] = 'install';
+6 -1
View File
@@ -1,3 +1,9 @@
ALTER TABLE `zt_host` ADD `type` varchar(30) NOT NULL DEFAULT 'normal' AFTER `admin`;
ALTER TABLE `zt_host` ADD `secret` varchar(50) NOT NULL DEFAULT '' AFTER `type`;
ALTER TABLE `zt_host` ADD `token` varchar(50) NOT NULL DEFAULT '' AFTER `secret`;
ALTER TABLE `zt_host` ADD `expiredDate` datetime NOT NULL AFTER `token`;
ALTER TABLE `zt_host` ADD `virtualSoftware` varchar(30) NOT NULL DEFAULT '' AFTER `expiredDate`;
ALTER TABLE `zt_host`
DROP COLUMN `cabinet`,
DROP COLUMN `cpuRate`,
@@ -58,7 +64,6 @@ h.`createdDate` = a.`createdDate`,
h.`editedBy` = a.`editedBy`,
h.`editedDate` = a.`editedDate`,
h.`group` = a.`group`,
h.`type` = a.`type`,
h.`deleted` = a.`deleted`
WHERE
h.`assetID` = a.`id`;
+3
View File
@@ -1 +1,4 @@
ALTER TABLE `zt_image` ADD `localName` VARCHAR(64) NOT NULL AFTER `name`;
ALTER TABLE `zt_image` ADD `restoreDate` datetime NOT NULL AFTER `createdDate`;
ALTER TABLE `zt_ticket` MODIFY `resolution` text NOT NULL;
+1
View File
@@ -7359,6 +7359,7 @@ CREATE TABLE `zt_image` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`host` int(11) unsigned NOT NULL DEFAULT 0,
`name` varchar(64) NOT NULL DEFAULT '',
`localName` varchar(64) NOT NULL DEFAULT '',
`address` varchar(64) NOT NULL DEFAULT '',
`path` varchar(64) NOT NULL DEFAULT '',
`status` varchar(20) NOT NULL DEFAULT '',
+1
View File
@@ -49,6 +49,7 @@ $config->action->objectNameFields['stage'] = 'name';
$config->action->objectNameFields['apistruct'] = 'name';
$config->action->objectNameFields['repo'] = 'name';
$config->action->objectNameFields['dataview'] = 'name';
$config->action->objectNameFields['zahost'] = 'name';
$config->action->objectNameFields['zanode'] = 'name';
$config->action->commonImgSize = 870;
+8
View File
@@ -237,6 +237,10 @@ $lang->action->desc->relieved = '$date, relieved by <strong>$actor</
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
$lang->action->desc->createdsnapshot = '$date, <strong>$actor</strong> creates a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->restoredsnapshot = '$date, <strong>$actor</strong> restored a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->editsnapshot = '$date, <strong>$actor</strong> edited the snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->deletesnapshot = '$date, <strong>$actor</strong> deleted snapshot <strong>$extra</strong>。' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
@@ -419,6 +423,10 @@ $lang->action->label->switchtolight = 'switch from ALM mode to light mod
$lang->action->label->linkedrepo = 'Linked Code Repo';
$lang->action->label->unlinkedrepo = 'Unlinked Code Repo';
$lang->action->label->unlinkproduct = 'Unlinked Product';
$lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass;
+8
View File
@@ -237,6 +237,10 @@ $lang->action->desc->relieved = '$date, relieved by <strong>$actor</
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
$lang->action->desc->createdsnapshot = '$date, <strong>$actor</strong> creates a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->restoredsnapshot = '$date, <strong>$actor</strong> restored a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->editsnapshot = '$date, <strong>$actor</strong> edited the snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->deletesnapshot = '$date, <strong>$actor</strong> deleted snapshot <strong>$extra</strong>。' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> created a child task <strong>$extra</strong>。' . "\n";
@@ -419,6 +423,10 @@ $lang->action->label->switchtolight = 'switch from ALM mode to light mod
$lang->action->label->linkedrepo = 'Linked Code Repo';
$lang->action->label->unlinkedrepo = 'Unlinked Code Repo';
$lang->action->label->unlinkproduct = 'Unlinked Product';
$lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass;
+8
View File
@@ -237,6 +237,10 @@ $lang->action->desc->relieved = '$date, relieved by <strong>$actor</
$lang->action->desc->switchtolight = '$date, Switch from ALM mode to light mode by <strong>'. $lang->admin->system .'</strong>.' . "\n";
$lang->action->desc->getvnc = '$date, Remote control <strong>$extra</strong> by <strong>$actor</strong> .' . "\n";
$lang->action->desc->unlinkproduct = '$date, the project is disassociated from the $extra, synchronization disassociates the ' . $lang->executionCommon . 's of the project from the $extra.' . "\n";
$lang->action->desc->createdsnapshot = '$date, <strong>$actor</strong> creates a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->restoredsnapshot = '$date, <strong>$actor</strong> restored a snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->editsnapshot = '$date, <strong>$actor</strong> edited the snapshot <strong>$extra</strong>。' . "\n";
$lang->action->desc->deletesnapshot = '$date, <strong>$actor</strong> deleted snapshot <strong>$extra</strong>。' . "\n";
/* Used to describe the history of operations related to parent-child tasks. */
$lang->action->desc->createchildren = '$date, <strong>$actor</strong> a créé un sous-tâche <strong>$extra</strong>。' . "\n";
@@ -419,6 +423,10 @@ $lang->action->label->switchtolight = 'switch from ALM mode to light mod
$lang->action->label->linkedrepo = 'Linked Code Repo';
$lang->action->label->unlinkedrepo = 'Unlinked Code Repo';
$lang->action->label->unlinkproduct = 'Unlinked Product';
$lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass();
+8
View File
@@ -237,6 +237,10 @@ $lang->action->desc->relieved = '$date, 由 <strong>$actor</strong>
$lang->action->desc->switchtolight = '$date, 由于 <strong>'. $lang->admin->system .'</strong> 从全生命周期管理模式切换为轻量管理模式,项目访问控制由项目集内公开调整为私有。' . "\n";
$lang->action->desc->getvnc = '$date, <strong>$actor</strong>对执行节点 <strong>$extra</strong> 进行了远程操控。' . "\n";
$lang->action->desc->unlinkproduct = '$date, 系统判断由于' . $lang->executionCommon . '所属项目与$extra取消关联,同步将' . $lang->executionCommon . '与$extra取消关联。' . "\n";
$lang->action->desc->createdsnapshot = '$date, <strong>$actor</strong> 创建了快照 <strong>$extra</strong>。' . "\n";
$lang->action->desc->restoredsnapshot = '$date, <strong>$actor</strong> 还原了快照 <strong>$extra</strong>。' . "\n";
$lang->action->desc->editsnapshot = '$date, <strong>$actor</strong> 编辑了快照 <strong>$extra</strong>。' . "\n";
$lang->action->desc->deletesnapshot = '$date, <strong>$actor</strong> 删除了快照 <strong>$extra</strong>。' . "\n";
/* 用来描述和父子任务相关的操作历史记录。*/
$lang->action->desc->createchildren = '$date, 由 <strong>$actor</strong> 创建子任务 <strong>$extra</strong>。' . "\n";
@@ -419,6 +423,10 @@ $lang->action->label->switchtolight = '从全生命周期管理模式切
$lang->action->label->linkedrepo = '关联代码库到';
$lang->action->label->unlinkedrepo = '取消了项目与代码库的关联';
$lang->action->label->unlinkproduct = '取消了与产品的关联';
$lang->action->label->createdsnapshot = '创建了快照';
$lang->action->label->restoredsnapshot = '还原了快照';
$lang->action->label->editsnapshot = '编辑了快照';
$lang->action->label->deletesnapshot = '编辑了快照';
/* 动态信息按照对象分组 */
$lang->action->dynamicAction = new stdclass();
+22 -12
View File
@@ -1239,18 +1239,23 @@ $lang->zahost->methodOrder[30] = 'downloadImage';
$lang->zahost->methodOrder[35] = 'cancelDownload';
$lang->resource->zanode = new stdclass();
$lang->resource->zanode->browse = 'browse';
$lang->resource->zanode->create = 'create';
$lang->resource->zanode->edit = 'edit';
$lang->resource->zanode->destroy = 'destroy';
$lang->resource->zanode->reboot = 'reboot';
$lang->resource->zanode->suspend = 'suspend';
$lang->resource->zanode->resume = 'resume';
$lang->resource->zanode->getVNC = 'getVNC';
$lang->resource->zanode->start = 'boot';
$lang->resource->zanode->close = 'shutdown';
$lang->resource->zanode->view = 'view';
$lang->resource->zanode->createImage = 'createImage';
$lang->resource->zanode->browse = 'browse';
$lang->resource->zanode->create = 'create';
$lang->resource->zanode->edit = 'edit';
$lang->resource->zanode->destroy = 'destroy';
$lang->resource->zanode->reboot = 'reboot';
$lang->resource->zanode->suspend = 'suspend';
$lang->resource->zanode->resume = 'resume';
$lang->resource->zanode->getVNC = 'getVNC';
$lang->resource->zanode->start = 'boot';
$lang->resource->zanode->close = 'shutdown';
$lang->resource->zanode->view = 'view';
$lang->resource->zanode->createImage = 'createImage';
$lang->resource->zanode->browseSnapshot = 'browseSnapshot';
$lang->resource->zanode->createSnapshot = 'createSnapshot';
$lang->resource->zanode->editSnapshot = 'editSnapshot';
$lang->resource->zanode->restoreSnapshot = 'restoreSnapshot';
$lang->resource->zanode->deleteSnapshot = 'deleteSnapshot';
$lang->zanode->methodOrder[0] = 'browse';
$lang->zanode->methodOrder[5] = 'create';
@@ -1264,6 +1269,11 @@ $lang->zanode->methodOrder[40] = 'start';
$lang->zanode->methodOrder[45] = 'close';
$lang->zanode->methodOrder[50] = 'view';
$lang->zanode->methodOrder[55] = 'createImage';
$lang->zanode->methodOrder[60] = 'browseSnapshot';
$lang->zanode->methodOrder[65] = 'createSnapshot';
$lang->zanode->methodOrder[70] = 'editSnapshot';
$lang->zanode->methodOrder[75] = 'restoreSnapshot';
$lang->zanode->methodOrder[80] = 'deleteSnapshot';
$lang->resource->repo = new stdclass();
$lang->resource->repo->browse = 'browseAction';
+8 -3
View File
@@ -43,8 +43,13 @@ class zahost extends control
$this->loadModel('search')->setSearchParams($this->config->zahost->search);
$showFeature = false;
$skipAutomation = !empty($this->config->global->skipAutomation) ? $this->config->global->skipAutomation : '';
if(strpos(",$skipAutomation,", $this->app->user->account) === false) $showFeature = true;
$accounts = !empty($this->config->global->skipAutomation) ? $this->config->global->skipAutomation : '';
if(strpos(",$accounts,", $this->app->user->account) === false)
{
$showFeature = true;
$accounts .= ',' . $this->app->user->account;
$this->loadModel('setting')->setItem('system.common.global.skipAutomation', $accounts);
}
$this->view->title = $this->lang->zahost->common;
$this->view->hostList = $hostList;
@@ -164,7 +169,7 @@ class zahost extends control
}
$this->dao->update(TABLE_ZAHOST)->set('deleted')->eq(1)->where('id')->eq($hostID)->exec();
$this->loadModel('action')->create('zahost', $hostID, 'deleted');
$this->loadModel('action')->create('zahost', $hostID, 'deleted', '', $extra = ACTIONMODEL::CAN_UNDELETED);
/* if ajax request, send result. */
if($this->server->ajax)
+1
View File
@@ -20,3 +20,4 @@
.btn-info {background-color: unset;}
.icon-refresh {font-size: 15px;}
.load-indicator:after {top: 33%;}
.btn.disabled i {color: #fff;}
-1
View File
@@ -76,7 +76,6 @@ function setIframeHeight(iframe)
{
var height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight
iframe.height = height+10;
console.log(1111, iframe.height)
}
}
}
+4 -1
View File
@@ -85,7 +85,10 @@ class zahostModel extends model
$this->dao->update(TABLE_ZAHOST)->data($hostInfo)
->batchCheck($this->config->zahost->create->requiredFields, 'notempty')
->batchCheck('diskSize,memory', 'float');
->batchCheck('diskSize,memory', 'float')
->check('name', 'unique', "id != $hostID and type in ('vhost', 'zahost')")
->autoCheck();
if(dao::isError()) return false;
$ping = $this->checkAddress($hostInfo->extranet);
+8 -26
View File
@@ -131,43 +131,25 @@
<div class="detail-title"><?php echo $lang->zahost->desc;?></div>
<div class="detail-content article-content"><?php echo !empty($zahost->desc) ? htmlspecialchars_decode($zahost->desc) : $lang->noData;?></div>
</div>
<?php if(!empty($nodeList)): ?>
</div>
<?php if(commonModel::hasPriv('zanode', 'browse')):?>
<div class="cell">
<div class="detail">
<div class="detail-title"><?php echo $lang->zahost->browseNode;?></div>
<?php if(!empty($nodeList)): ?>
<div class="detail-content article-content">
<?php echo "<iframe width='100%' id='nodesIframe' src='" . $this->createLink('zanode', 'list', "hostID=$zahost->id", '', true) . "' frameborder='no' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true' allowtransparency='true' scrolling='auto' onload='setIframeHeight(this)' style='min-height:300px;'></iframe>";?>
<!-- <table class='table has-sort-head table-fixed' id='nodeList'>
<thead>
<tr>
<th class='c-name'><?php common::printOrderLink('name', $orderBy, $vars, $lang->zahost->name);?></th>
<th class='c-cpu'><?php common::printOrderLink('cpuCores', $orderBy, $vars, $lang->zanode->cpuCores);?></th>
<th class='c-number'><?php common::printOrderLink('memory', $orderBy, $vars, $lang->zanode->memory);?></th>
<th class='c-number'><?php common::printOrderLink('diskSize', $orderBy, $vars, $lang->zanode->diskSize);?></th>
<th class='c-os'><?php common::printOrderLink('osName', $orderBy, $vars, $lang->zanode->osName);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->zanode->status);?></th>
</tr>
</thead>
<tbody>
<?php foreach($nodeList as $node):?>
<tr>
<td title="<?php echo $node->name;?>"><?php echo html::a($this->createLink('zanode', 'view', "id=$node->id"), $node->name, '_target', "");?></td>
<td><?php echo zget($config->zanode->os->cpuCores, $node->cpuCores);?></td>
<td><?php echo $node->memory . $this->lang->zahost->unitList['GB'];?></td>
<td><?php echo $node->diskSize . $this->lang->zahost->unitList['GB'];?></td>
<td><?php echo $node->osName;?></td>
<td><?php echo zget($lang->zanode->statusList, $node->status);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table> -->
</div>
<?php else: ?>
<div class="detail-content article-content"><?php echo $lang->noData;?></div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php
$canBeChanged = common::canBeChanged('zahost', $zahost);
if($canBeChanged) $actionFormLink = $this->createLink('action', 'comment', "objectType=zahost&objectID=$zahost->hostID");
?>
</div>
<?php endif; ?>
<?php $this->printExtendFields($zahost, 'div', "position=left&inForm=0&inCell=1");?>
<div class='main-actions'>
<div class="btn-toolbar">
+156 -2
View File
@@ -44,8 +44,13 @@ class zanode extends control
$this->loadModel('search')->setSearchParams($this->config->zanode->search);
$showFeature = false;
$skipAutomation = !empty($this->config->global->skipAutomation) ? $this->config->global->skipAutomation : '';
if(strpos(",$skipAutomation,", $this->app->user->account) === false) $showFeature = true;
$accounts = !empty($this->config->global->skipAutomation) ? $this->config->global->skipAutomation : '';
if(strpos(",$accounts,", $this->app->user->account) === false)
{
$showFeature = true;
$accounts .= ',' . $this->app->user->account;
$this->loadModel('setting')->setItem('system.common.global.skipAutomation', $accounts);
}
$this->view->title = $this->lang->zanode->common;
$this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
@@ -73,6 +78,10 @@ class zanode extends control
*/
public function list($hostID, $orderBy = 'id_desc')
{
if(!commonModel::hasPriv('zanode', 'browse'))
{
$this->loadModel('common')->deny('zanode', 'browse');
}
$this->view->title = $this->lang->zanode->common;
$this->view->nodeList = $this->loadModel("zanode")->getListByHost($hostID, $orderBy);
$this->view->orderBy = $orderBy;
@@ -155,6 +164,7 @@ class zanode extends control
$this->view->token = !empty($vnc->token) ? $vnc->token:'';
$this->view->title = $this->lang->zanode->view;
$this->view->zanode = $node;
$this->view->snapshotList = $this->zanode->getSnapshotList($id);
$this->view->actions = $this->loadModel('action')->getList('zanode', $id);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->display();
@@ -276,6 +286,90 @@ class zanode extends control
$this->display();
}
/**
* Create snapshot.
*
* @param int $zanodeID
* @access public
* @return void
*/
public function createSnapshot($nodeID = 0)
{
$node = $this->zanode->getNodeByID($nodeID);
if($_POST)
{
$this->zanode->createSnapshot($nodeID);
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
return $this->send($response);
}
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
}
$this->view->node = $node;
$this->display();
}
/**
* Edit Snapshot.
*
* @param int $snapshotID
* @access public
* @return void
*/
public function editSnapshot($snapshotID)
{
$snapshot = $this->zanode->getImageByID($snapshotID);
if($_POST)
{
$this->zanode->editSnapshot($snapshotID);
if(dao::isError())
{
$response['result'] = 'fail';
$response['message'] = dao::getError();
return $this->send($response);
}
$this->loadModel('action')->create('zanode', $snapshot->host, 'editSnapshot', '', $snapshot->localName ? $snapshot->localName : $snapshot->name);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
}
$this->view->snapshot = $snapshot;
$this->display();
}
/**
* Delete Snapshot.
*
* @param int $snapshotID
* @param string $confirm
* @access public
* @return void
*/
public function deleteSnapshot($snapshotID, $confirm = 'no')
{
if($confirm == 'no')
{
return print(js::confirm($this->lang->zanode->confirmDeleteSnapshot, inlink('deleteSnapshot', "snapshotID={$snapshotID}&confirm=yes")));
}
$result = $this->zanode->deleteSnapshot($snapshotID);
if($result !== true)
{
return print(js::alert($result));
}
else
{
if(isonlybody()) return print(js::alert($this->lang->zanode->actionSuccess) . js::reload('parent.parent'));
return print(js::alert($this->lang->zanode->actionSuccess) . js::locate($this->createLink('zanode', 'browse'), 'parent'));
}
}
/**
* Desctroy node.
*
@@ -324,6 +418,66 @@ class zanode extends control
$this->display();
}
/**
* Browse snapshot.
*
* @param int $nodeID
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browseSnapshot($nodeID, $browseType = 'all', $param = 0, $orderBy = 'id', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->app->loadLang('zahost');
$this->app->loadClass('pager', $static = true);
$pager = pager::init($recTotal, $recPerPage, $pageID);
$snapshotList = $this->zanode->getSnapshotList($nodeID, $browseType, $param, $orderBy, $pager);
$this->view->title = $this->lang->zanode->browseSnapshot;
$this->view->nodeID = $nodeID;
$this->view->node = $this->zanode->getNodeByID($nodeID);
$this->view->snapshotList = $snapshotList;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->pager = $pager;
$this->view->param = $param;
$this->view->orderBy = $orderBy;
$this->view->browseType = $browseType;
$this->display();
}
/**
* Restore node.
*
* @param int $nodeID
* @return void
*/
public function restoreSnapshot($nodeID, $snapshotID, $confirm = 'no')
{
if($confirm == 'no')
{
return print(js::confirm($this->lang->zanode->confirmRestore, inlink('restoreSnapshot', "nodeID={$nodeID}&snapshotID={$snapshotID}&confirm=yes")));
}
$this->zanode->restoreSnapshot($nodeID, $snapshotID);
if(dao::isError())
{
return print(js::alert(dao::getError()) . js::reload('parent'));
}
else
{
if(isonlybody()) return print(js::alert($this->lang->zanode->actionSuccess) . js::reload('parent.parent'));
return print(js::alert($this->lang->zanode->actionSuccess) . js::locate($this->createLink('zanode', 'browse'), 'parent'));
}
}
/**
* Ajax get template pairs by api.
*
+6
View File
@@ -0,0 +1,6 @@
#main{min-width: 0!important;padding:0!important;}
body{background-color: #fff!important;}
.c-createdBy {width: 100px;}
.c-datetime {width: 130px;}
.c-status {width: 120px;}
+1
View File
@@ -16,3 +16,4 @@
.checkStatus{color: #313c52;}
.node-not-wrap{white-space: nowrap;}
.btn-info {background-color: unset;}
.btn.disabled i {color: #fff;}
+7
View File
@@ -0,0 +1,7 @@
$(function()
{
var myPager = $('.pager').data('zui.pager');
myPager.options.menuDirection = 'dropdown';
myPager.set();
});
+20
View File
@@ -160,6 +160,14 @@ $('.btn-pwd-copy').live('click', function()
}, 2000)
})
$('#jumpManual').click(function()
{
var encodedHelpPageUrl = encodeURIComponent('https://www.zentao.net/book/zentaopms/974.html?fullScreen=zentao');
var urlForNewTab = window.location.origin + '#app=help&url=' + encodedHelpPageUrl;
window.open(urlForNewTab)
})
$(function(){
checkServiceStatus();
checkInterval = setInterval(() => {
@@ -171,3 +179,15 @@ $(function(){
checkServiceStatus();
}, 2000);
})
/**
* Edit Snapshot.
*
* @param string $link
* @access public
* @return void
*/
function editSnapshot(link)
{
$('#editSnapshot').attr('href', link).click();
}
+17
View File
@@ -79,6 +79,22 @@ $lang->zanode->createImageSuccess = 'Successed, You can use this image to create
$lang->zanode->createImageFail = 'Failed to create';
$lang->zanode->createImageButton = 'Create image';
$lang->zanode->snapshotName = 'Snapshot Name';
$lang->zanode->browseSnapshot = 'Snapshot List';
$lang->zanode->createSnapshot = 'Create Snapshot';
$lang->zanode->editSnapshot = 'Edit Snapshot';
$lang->zanode->restoreSnapshot = 'Revert Snapshot';
$lang->zanode->deleteSnapshot = 'Delete Snapshot';
$lang->zanode->snapshotEmpty = 'No snapshots';
$lang->zanode->confirmDeleteSnapshot = "The snapshot cannot be restored from the recycle bin after being deleted. Are you sure to continue?";
$lang->zanode->snapshot->statusList['creating'] = 'Creating';
$lang->zanode->snapshot->statusList['completed'] = 'Create Completed';
$lang->zanode->snapshot->statusList['failed'] = 'Create Failed';
$lang->zanode->snapshot->statusList['restoring'] = 'Restoring';
$lang->zanode->snapshot->statusList['restore_failed'] = 'Restore Failed';
$lang->zanode->snapshot->statusList['restore_completed'] = 'Restore Completed';
$lang->zanode->imageNameEmpty = 'Name can not be empty.';
$lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.';
@@ -101,6 +117,7 @@ $lang->zanode->statusList['shutodown'] = 'shutdown';
$lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
+28 -7
View File
@@ -42,12 +42,14 @@ $lang->zanode->vnc = 'VNC Port';
$lang->zanode->destroyAt = 'Destroy Time';
$lang->zanode->creater = 'Creator';
$lang->zanode->createdDate = 'Create Date';
$lang->zanode->confirmDelete = "Are you sure about destroying the ZenAgent Node";
$lang->zanode->confirmBoot = "Are you sure to start the ZenAgent Node";
$lang->zanode->confirmReboot = "Are you sure to restart the ZenAgent Node";
$lang->zanode->confirmShutdown = "Are you sure to shutdown the ZenAgent Node";
$lang->zanode->confirmSuspend = "Are you sure to suspend the ZenAgent Node";
$lang->zanode->confirmResume = "Are you sure to resume the ZenAgent Node";
$lang->zanode->confirmDelete = "Are you sure about destroying the ZenAgent Node?";
$lang->zanode->confirmBoot = "Are you sure to start the ZenAgent Node?";
$lang->zanode->confirmReboot = "Are you sure to restart the ZenAgent Node?";
$lang->zanode->confirmShutdown = "Are you sure to shutdown the ZenAgent Node?";
$lang->zanode->confirmSuspend = "Are you sure to suspend the ZenAgent Node?";
$lang->zanode->confirmResume = "Are you sure to resume the ZenAgent Node?";
$lang->zanode->confirmRestore = "Are you sure to restore the ZenAgent Node?";
$lang->zanode->confirmRestore = "The ZenAgent Node will be restored to this snapshot state, are you sure you want to continue?";
$lang->zanode->actionSuccess = 'Success';
$lang->zanode->deleted = "Deleted";
$lang->zanode->scriptPath = "Script path";
@@ -79,7 +81,25 @@ $lang->zanode->createImageSuccess = 'Successed, You can use this image to create
$lang->zanode->createImageFail = 'Failed to create';
$lang->zanode->createImageButton = 'Create image';
$lang->zanode->imageNameEmpty = 'Name can not be empty.';
$lang->zanode->snapshotName = 'Snapshot Name';
$lang->zanode->browseSnapshot = 'Snapshot List';
$lang->zanode->createSnapshot = 'Create Snapshot';
$lang->zanode->editSnapshot = 'Edit Snapshot';
$lang->zanode->restoreSnapshot = 'Revert Snapshot';
$lang->zanode->deleteSnapshot = 'Delete Snapshot';
$lang->zanode->snapshotEmpty = 'No snapshots';
$lang->zanode->confirmDeleteSnapshot = "The snapshot cannot be restored from the recycle bin after being deleted. Are you sure to continue?";
$lang->zanode->snapshot->statusList['creating'] = 'Creating';
$lang->zanode->snapshot->statusList['completed'] = 'Create Completed';
$lang->zanode->snapshot->statusList['failed'] = 'Create Failed';
$lang->zanode->snapshot->statusList['restoring'] = 'Restoring';
$lang->zanode->snapshot->statusList['restore_failed'] = 'Restore Failed';
$lang->zanode->snapshot->statusList['restore_completed'] = 'Restore Completed';
$lang->zanode->imageNameEmpty = 'Name can not be empty.';
$lang->zanode->snapStatusError = 'Snapshot is not ready.';
$lang->zanode->snapRestoring = 'Snapshot is restoring.';
$lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.';
@@ -101,6 +121,7 @@ $lang->zanode->statusList['shutodown'] = 'shutdown';
$lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
+17
View File
@@ -79,6 +79,22 @@ $lang->zanode->createImageSuccess = 'Successed, You can use this image to create
$lang->zanode->createImageFail = 'Failed to create';
$lang->zanode->createImageButton = 'Create image';
$lang->zanode->snapshotName = 'Snapshot Name';
$lang->zanode->browseSnapshot = 'Snapshot List';
$lang->zanode->createSnapshot = 'Create Snapshot';
$lang->zanode->editSnapshot = 'Edit Snapshot';
$lang->zanode->restoreSnapshot = 'Revert Snapshot';
$lang->zanode->deleteSnapshot = 'Delete Snapshot';
$lang->zanode->snapshotEmpty = 'No snapshots';
$lang->zanode->confirmDeleteSnapshot = "The snapshot cannot be restored from the recycle bin after being deleted. Are you sure to continue?";
$lang->zanode->snapshot->statusList['creating'] = 'Creating';
$lang->zanode->snapshot->statusList['completed'] = 'Create Completed';
$lang->zanode->snapshot->statusList['failed'] = 'Create Failed';
$lang->zanode->snapshot->statusList['restoring'] = 'Restoring';
$lang->zanode->snapshot->statusList['restore_failed'] = 'Restore Failed';
$lang->zanode->snapshot->statusList['restore_completed'] = 'Restore Completed';
$lang->zanode->imageNameEmpty = 'Name can not be empty.';
$lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.';
@@ -101,6 +117,7 @@ $lang->zanode->statusList['shutodown'] = 'shutdown';
$lang->zanode->statusList['destroy_fail'] = 'Destroy Fail';
$lang->zanode->statusList['wait'] = 'Initializing';
$lang->zanode->statusList['online'] = 'Online';
$lang->zanode->statusList['restoring'] = 'Restoring';
$lang->zanode->initNotice = "Succeeded. Please initialize the execution node or return to the list.";
$lang->zanode->initButton = "Initialize";
+21
View File
@@ -48,6 +48,7 @@ $lang->zanode->confirmReboot = "您确定重启执行节点吗?";
$lang->zanode->confirmShutdown = "您确定关闭执行节点吗?";
$lang->zanode->confirmSuspend = "您确定休眠执行节点吗?";
$lang->zanode->confirmResume = "您确定恢复执行节点吗?";
$lang->zanode->confirmRestore = "执行节点将会还原至此快照状态,您确定要继续么?";
$lang->zanode->actionSuccess = '操作成功';
$lang->zanode->deleted = "已删除";
$lang->zanode->scriptPath = "脚本目录";
@@ -79,7 +80,26 @@ $lang->zanode->createImageSuccess = '镜像导出成功,您可以使用此镜
$lang->zanode->createImageFail = '镜像导出失败';
$lang->zanode->createImageButton = '去创建';
$lang->zanode->snapshotName = '快照名称';
$lang->zanode->browseSnapshot = '快照列表';
$lang->zanode->createSnapshot = '创建快照';
$lang->zanode->editSnapshot = '编辑快照';
$lang->zanode->restoreSnapshot = '还原快照';
$lang->zanode->deleteSnapshot = '删除快照';
$lang->zanode->snapshotEmpty = '无快照';
$lang->zanode->confirmDeleteSnapshot = "快照被删除后无法从回收站中还原,您确定继续么?";
$lang->zanode->snapshot->statusList['creating'] = '创建中';
$lang->zanode->snapshot->statusList['completed'] = '创建完成';
$lang->zanode->snapshot->statusList['failed'] = '创建失败';
$lang->zanode->snapshot->statusList['restoring'] = '还原中';
$lang->zanode->snapshot->statusList['restore_failed'] = '还原失败';
$lang->zanode->snapshot->statusList['restore_completed'] = '还原成功';
$lang->zanode->imageNameEmpty = '名称不能为空';
$lang->zanode->imageNameEmpty = '名称不能为空';
$lang->zanode->snapStatusError = '快照不可用';
$lang->zanode->snapRestoring = '快照正在还原中';
$lang->zanode->runTimeout = '自动执行失败,请检查宿主机和执行节点状态';
@@ -101,6 +121,7 @@ $lang->zanode->statusList['shutodown'] = '已关机';
$lang->zanode->statusList['destroy_fail'] = '销毁失败';
$lang->zanode->statusList['wait'] = '初始化中';
$lang->zanode->statusList['online'] = '已上架';
$lang->zanode->statusList['restoring'] = '还原中';
$lang->zanode->initNotice = "保存成功,请初始化执行节点或返回列表。";
$lang->zanode->initButton = "去初始化";
+193 -1
View File
@@ -28,6 +28,10 @@ class zanodemodel extends model
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;
*
@@ -167,6 +171,173 @@ class zanodemodel extends model
return false;
}
/**
* Create Snapshot by zanode.
*
* @param int $zanodeID
* @access public
* @return void
*/
public function createSnapshot($zanodeID = 0)
{
$data = fixer::input('post')->get();
if(empty($data->name)) dao::$errors['name'] = $this->lang->zanode->imageNameEmpty;
if(dao::isError()) return false;
$node = $this->getNodeByID($zanodeID);
$newSnapshot = new stdClass();
$newSnapshot->host = $node->id;
$newSnapshot->name = $data->name;
$newSnapshot->desc = $data->desc;
$newSnapshot->status = 'creating';
$newSnapshot->osName = $node->osName;
$newSnapshot->from = 'snapshot';
$newSnapshot->createdBy = $this->app->user->account;
$newSnapshot->createdDate = helper::now();
$this->dao->insert(TABLE_IMAGE)
->data($newSnapshot)
->autoCheck()
->exec();
if(dao::isError()) return false;
$newID = $this->dao->lastInsertID();
/* Prepare create params. */
$agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
$param = array(array(
'name' => $data->name,
'task' => $newID,
'type' => 'createSnap',
'vm' => $node->name
));
$result = json_decode(commonModel::http($agnetUrl . static::SNAPSHOT_CREATE_PATH, json_encode($param,JSON_NUMERIC_CHECK), null, array("Authorization:$node->tokenSN")));
if(!empty($result) and $result->code == 'success')
{
$this->loadModel('action')->create('zanode', $zanodeID, 'createdSnapshot', '', $data->name);
return $newID;
}
$this->dao->delete()->from(TABLE_IMAGE)->where('id')->eq($newID)->exec();
dao::$errors[] = (!empty($result) and !empty($result->msg)) ? $result->msg : $this->app->lang->fail;
return false;
}
/**
* Edit Snapshot.
*
* @param int $snapshotID
* @access public
* @return bool
*/
public function editSnapshot($snapshotID)
{
$data = fixer::input('post')->get();
if(empty($data->name)) dao::$errors['name'] = $this->lang->zanode->imageNameEmpty;
if(dao::isError()) return false;
$newSnapshot = new stdClass();
$newSnapshot->localName = $data->name;
$newSnapshot->desc = $data->desc;
$this->dao->update(TABLE_IMAGE)
->data($newSnapshot)
->where('id')->eq($snapshotID)
->autoCheck()
->exec();
return true;
}
/**
* Restore Snapshot to zanode.
*
* @param int $zanodeID
* @access public
* @return void
*/
public function restoreSnapshot($zanodeID = 0, $snapshotID = 0)
{
$node = $this->getNodeByID($zanodeID);
$snap = $this->getImageByID($snapshotID);
$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();
/* Prepare create params. */
$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), null, array("Authorization:$node->tokenSN")));
if(!empty($result) and $result->code == 'success')
{
$this->dao->update(TABLE_HOST)->set('status')->eq('restoring')->where('id')->eq($node->id)->exec();
$this->loadModel('action')->create('zanode', $zanodeID, 'restoredsnapshot', '', $snap->name);
return true;
}
$this->dao->update(TABLE_IMAGE)->set('status')->eq('completed')->where('id')->eq($snapshotID)->exec();
dao::$errors[] = (!empty($result) and !empty($result->msg)) ? $result->msg : $this->lang->zanode->apiError['fail'];
return false;
}
/**
* Delete Snapshot.
*
* @param int $id
* @access public
* @return void
*/
public function deleteSnapshot($snapshotID)
{
$snapshot = $this->getImageByID($snapshotID);
$node = $this->getNodeByID($snapshot->host);
if($node)
{
$agnetUrl = 'http://' . $node->ip . ':' . $node->hzap;
$param = (object)array(
'name' => $snapshot->name,
'task' => $snapshotID,
'vm' => $node->name
);
$result = commonModel::http($agnetUrl . static::SNAPSHOT_REMOVE_PATH, json_encode($param,JSON_NUMERIC_CHECK), array(), array("Authorization:$node->tokenSN"));
$result = json_decode($result);
if(!empty($result) and $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) and !empty($result->msg)) ? $result->msg : $this->lang->zanode->apiError['fail'];
return $error;
}
}
/**
* Action Node.
*
@@ -212,7 +383,7 @@ class zanodemodel extends model
public function destroy($id)
{
$node = $this->getNodeByID($id);
if($node)
{
$req = array( 'name' => $node->name );
@@ -520,6 +691,27 @@ class zanodemodel extends model
->fetch();
}
public function getSnapshotList($nodeID, $browseType = 'all', $param = 0, $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' and (time() - strtotime($snapshot->createdDate)) > 1800)
{
$this->dao->update(TABLE_IMAGE)->set('status')->eq('failed')->where('id')->eq($snapshot->id)->exec();
$snapshotList[$name]->status = 'failed';
}
}
return $snapshotList;
}
/**
* Get Node by id.
*
+5 -1
View File
@@ -85,6 +85,9 @@
$rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'";
$rebootAttr .= $node->status == 'shutoff' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$snapshotAttr = "title='{$lang->zanode->createSnapshot}'";
$snapshotAttr .= $node->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
common::printLink('zanode', 'getVNC', "id={$node->id}", "<i class='icon icon-remote'></i> ", (in_array($node->status ,array('running', 'launch', 'wait')) ? '_blank' : ''), "title='{$lang->zanode->getVNC}' class='btn desktop " . (in_array($node->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
if($node->status == "suspend")
{
@@ -105,13 +108,14 @@
}
common::printLink('zanode', 'reboot', "zanodeID={$node->id}", "<i class='icon icon-restart'></i> ", '', $rebootAttr);
common::printIcon('zanode', 'edit', "id={$node->id}", $node, 'list');
common::printLink('zanode', 'createSnapshot', "zanodeID={$node->id}", "<i class='icon icon-plus'></i> ", '', $snapshotAttr, true, true);
if(common::hasPriv('zanode', 'createImage') or common::hasPriv('zanode', 'destroy'))
{
echo "<div class='btn-group'>";
echo "<button type='button' class='btn dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}'><i class='icon-ellipsis-v'></i></button>";
echo "<ul class='dropdown-menu pull-right text-center' role='menu'>";
common::printIcon('zanode', 'edit', "id={$node->id}", $node, 'list', '', '', 'btn-action');
common::printLink('zanode', 'createImage', "zanodeID={$node->id}", "<i class='icon icon-export'></i> ", '', "class='btn btn-action iframe createImage' title='{$lang->zanode->createImage}' data-width='55%'", '', true);
common::printLink('zanode', 'destroy', "zanodeID={$node->id}", "<i class='icon icon-trash'></i> ", '', "title='{$lang->zanode->destroy}' class='btn btn-action' target='hiddenwin'");
echo "</ul>";
@@ -0,0 +1,66 @@
<?php
/**
* The snapshot browse view file of zahost module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology 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 <liyuchun@easycorp.ltd>
* @package zahost
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::set('nodeID', $nodeID);?>
<div id='mainContent' class='main-table'>
<?php $vars = "nodeID=$nodeID&browseType=all&param=0&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<?php if(empty($snapshotList)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->zanode->snapshotEmpty;?></span>
</p>
</div>
<?php else:?>
<table class='table has-sort-head table-fixed' id='snapshotList'>
<thead>
<tr>
<th class='c-name'><?php common::printOrderLink('name', $orderBy, $vars, $lang->zahost->image->name);?></th>
<th class='c-status'><?php echo $lang->zahost->status;?></th>
<th class='c-createdBy'><?php echo $lang->zahost->createdBy;?></th>
<th class='c-datetime'><?php echo $lang->zahost->createdDate;?></th>
<th class='c-actions-3'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php foreach($snapshotList as $snapshot):?>
<tr>
<?php
$snapshot->status = ($snapshot->status == 'restoring' && time() - strtotime($snapshot->restoreDate) > 600) ? 'restore_failed' : $snapshot->status;
$editAttr = $snapshot->status == 'failed' ? 'class="btn disabled"' : "title={$lang->zanode->editSnapshot} onclick='window.parent.editSnapshot(\"" . $this->createLink('zanode', 'editSnapshot', "snapshotID={$snapshot->id}") . "\")' class='btn'";
$restoreAttr = "title='{$lang->zanode->restoreSnapshot}' target='hiddenwin'";
$restoreAttr .= ($node->status !='running' or $snapshot->status == 'restoring' or $snapshot->status == 'failed') ? ' class="btn disabled"' : 'class="btn"';
$deleteAttr = "title='{$lang->zanode->deleteSnapshot}' target='hiddenwin'";
$deleteAttr .= (($snapshot->status == 'restoring' and (time() - strtotime($snapshot->restoreDate)) <= 600) or $snapshot->status == 'failed') ? ' class="btn disabled"' : 'class="btn"';
?>
<td title="<?php echo $snapshot->name;?>"><?php echo $snapshot->localName ? $snapshot->localName : $snapshot->name;?></td>
<td class='<?php echo $snapshot->status;?>'><?php echo zget($lang->zanode->snapshot->statusList, $snapshot->status, '');?></td>
<td class="c-createdBy"><?php echo zget($users, $snapshot->createdBy, '')?></td>
<td class='c-datetime'><?php echo $snapshot->createdDate;?></td>
<td class='c-actions'>
<?php if(common::hasPriv('zanode', 'editSnapshot')) echo html::a('###', '<i class="icon-edit"></i>', 'hiddenwin', $editAttr);?>
<?php if(common::hasPriv('zanode', 'restoreSnapshot')) echo html::a($this->createLink('zanode', 'restoreSnapshot', "nodeID={$nodeID}&snapshotID={$snapshot->id}"), '<i class="icon-restart"></i>', 'hiddenwin', $restoreAttr);?>
<?php if(common::hasPriv('zanode', 'deleteSnapshot')) echo html::a($this->createLink('zanode', 'deleteSnapshot', "snapshotID={$snapshot->id}"), '<i class="icon-trash"></i>', 'hiddenwin', $deleteAttr);?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</div>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>
@@ -0,0 +1,46 @@
<?php
/**
* The create file of snapshot of zanode.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology 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 chunsheng wang <chunsheng@cnezsoft.com>
* @package task
* @version
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('nodeID', $node->id);?>
<?php js::set('zanodeLang', $lang->zanode); ?>
<style>.body-modal #mainContent{width:90%}
</style>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2>
<span><?php echo $lang->zanode->createSnapshot;?></span>
</h2>
</div>
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->zanode->snapshotName;?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->zanode->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', '', "rows='6' class='form-control'");?></td>
</tr>
<tr>
<td colspan='3' class='text-center'>
<?php echo html::submitButton('', "");?>
</td>
</tr>
</table>
</form>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+45
View File
@@ -0,0 +1,45 @@
<?php
/**
* The edit file of snapshot of zanode.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology 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 chunsheng wang <chunsheng@cnezsoft.com>
* @package task
* @version
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php js::set('zanodeLang', $lang->zanode); ?>
<style>.body-modal #mainContent{width:90%}
</style>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2>
<span><?php echo $lang->zanode->editSnapshot;?></span>
</h2>
</div>
<form class="load-indicator main-form form-ajax" method='post' enctype='multipart/form-data' id='dataform'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->zanode->snapshotName;?></th>
<td class='required'><?php echo html::input('name', $snapshot->localName ? $snapshot->localName : $snapshot->name, "class='form-control'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->zanode->desc;?></th>
<td colspan='2'><?php echo html::textarea('desc', $snapshot->desc, "rows='6' class='form-control'");?></td>
</tr>
<tr>
<td colspan='3' class='text-center'>
<?php echo html::submitButton('', "");?>
</td>
</tr>
</table>
</form>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+1
View File
@@ -11,6 +11,7 @@
* @link http://www.zentao.net
*/
?>
<?php js::set('showFeature', false);?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php'; ?>
<div id='mainContent' class='main-table'>
<?php $vars = "id={$hostID}&orderBy=%s"; ?>
+21 -2
View File
@@ -55,7 +55,7 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->sshAddress; ?>:</div>
<div class="col-8 node-not-wrap">ssh <?php echo $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh; ?><?php echo " <button type='button' class='btn btn-info btn-mini btn-ssh-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>"; ?></div>
<div class="col-8 node-not-wrap"><?php echo $zanode->ssh ? 'ssh ' . $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh : ''; ?><?php echo $zanode->ssh ? " <button type='button' class='btn btn-info btn-mini btn-ssh-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>" : ''; ?></div>
</div>
<textarea style="display:none;" id="ssh-copy">ssh <?php echo $account . '@' . $zanode->ip . ' -p ' . $zanode->ssh; ?></textarea>
</div>
@@ -96,7 +96,7 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<div class="col-4">
<div class="main-row">
<div class="col-3 text-right"><?php echo $lang->zanode->defaultPwd; ?>:</div>
<div class="col-8"><?php echo $config->zanode->defaultPwd . ' ' . "<button type='button' class='btn btn-info btn-mini btn-pwd-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>"; ?></div>
<div class="col-8"><?php echo str_repeat('*', strlen($config->zanode->defaultPwd)) . ' ' . "<button type='button' class='btn btn-info btn-mini btn-pwd-copy'><i class='icon-common-copy icon-copy' title='" . $lang->zanode->copy . "'></i></button>"; ?></div>
<textarea style="display:none;" id="pwd-copy"><?php echo $config->zanode->defaultPwd; ?></textarea>
</div>
</div>
@@ -149,6 +149,20 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
<div class="detail-content article-content"><?php echo !empty($zanode->desc) ? htmlspecialchars_decode($zanode->desc) : $lang->noData; ?></div>
</div>
</div>
<?php if(common::hasPriv('zanode', 'browseSnapshot')):?>
<div class="cell">
<div class="detail zanode-detail">
<div class="detail-title"><?php echo $lang->zanode->browseSnapshot;?></div>
<?php if(!empty($snapshotList)): ?>
<div class="detail-content article-content">
<?php echo "<iframe width='100%' id='nodesIframe' src='" . $this->createLink('zanode', 'browseSnapshot', "nodeID=$zanode->id", '', true) . "' frameborder='no' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true' allowtransparency='true' scrolling='auto' onload='setIframeHeight(this)' style='min-height:300px;'></iframe>";?>
</div>
<?php else: ?>
<div class="detail-content article-content"><?php echo $lang->noData; ?></div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php $this->printExtendFields($zanode, 'div', "position=left&inForm=0&inCell=1"); ?>
<div class='main-actions'>
<div class="btn-toolbar">
@@ -164,6 +178,9 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
$rebootAttr = "title='{$lang->zanode->reboot}' target='hiddenwin'";
$rebootAttr .= $zanode->status == 'shutoff' ? ' class="btn disabled"' : "class='btn' target='hiddenwin' onclick='if(confirm(\"{$lang->zanode->confirmReboot}\")==false) return false;'";
$snapshotAttr = "title='{$lang->zanode->createSnapshot}'";
$snapshotAttr .= $zanode->status != 'running' ? ' class="btn disabled"' : ' class="btn iframe"';
common::printLink('zanode', 'getVNC', "id={$zanode->id}", "<i class='icon icon-remote'></i> " . $lang->zanode->getVNC, in_array($zanode->status ,array('running', 'launch', 'wait')) ? '_blank' : '', "title='{$lang->zanode->getVNC}' class='btn desktop " . (in_array($zanode->status ,array('running', 'launch', 'wait')) ? '':'disabled') . "'", '');
if($zanode->status == "suspend")
@@ -185,11 +202,13 @@ $account = strpos($zanode->osName, "windows") ? $config->zanode->defaultWinAccou
}
common::printLink('zanode', 'reboot', "zanodeID={$zanode->id}", "<i class='icon icon-restart'></i> " . $lang->zanode->rebootNode, '', $rebootAttr);
common::printLink('zanode', 'createSnapshot', "zanodeID={$zanode->id}", "<i class='icon icon-plus'></i> " . $lang->zanode->createSnapshot, '', $snapshotAttr, true, true);
}
?>
<div class='divider'></div>
<?php echo $this->zanode->buildOperateMenu($zanode, 'view'); ?>
<a id='editSnapshot' href='' class='iframe'></a>
</div>
</div>
</div>