Merge branch 'sprint/285' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/285_tsj_83723

This commit is contained in:
tianshujie
2023-02-08 10:42:52 +08:00
57 changed files with 875 additions and 125 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
@@ -368,7 +368,7 @@ $filter->doc->showfiles->get['recPerPage'] = 'int';
$filter->doc->showfiles->get['recTotal'] = 'int';
$filter->doc->showfiles->get['title'] = 'reg::any';
$filter->file->download->get['charset'] = 'reg::lang';
$filter->file->download->get['charset'] = 'reg::any';
$filter->mail->batchdelete->get['idList'] = 'reg::idList';
+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;
+33 -17
View File
@@ -4081,23 +4081,39 @@ REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) V
('all', 'process', 'classify', 'engineering', '工程支持', '1'),
('all', 'process', 'classify', 'project', '项目管理', '1');
REPLACE INTO `zt_process` (`id`, `name`, `type`, `abbr`, `desc`, `assignedTo`, `status`, `order`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `deleted`) VALUES
(11,'立项管理','project','PIM','','','',55,'admin','2020-01-09 10:29:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(12,'项目规划','project','PP','','','',60,'admin','2020-01-09 10:31:16','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(13,'项目监控','project','PMC','','','',65,'admin','2020-01-09 10:31:16','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(14,'风险管理','project','RSKM','','','',70,'admin','2020-01-09 10:31:16','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(15,'结项管理','project','PCM','','','',75,'admin','2020-01-09 10:31:16','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(16,'量化项目管理','project','QPM','','','',80,'admin','2020-01-09 10:31:16','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(17,'需求开发','engineering','RDM','','','',85,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(18,'设计开发','engineering','','','','',90,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(19,'实现与测试','engineering','EMBEDDED','','','',95,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(20,'系统测试','engineering','ST','','','',100,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(21,'客户验收','engineering','CA','','','',105,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(22,'质量保证','support','QA','','','',110,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(23,'配置管理','support','CM','','','',115,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(24,'度量分析','support','MA','','','',120,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(25,'原因分析与解决','support','CAR','','','',125,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0'),
(26,'决策分析','support','DAR','','','',130,'admin','2020-01-09 13:14:55','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0');
REPLACE INTO `zt_process` (`id`, `model`, `name`, `type`, `abbr`, `desc`, `assignedTo`, `status`, `order`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `deleted`) VALUES
(11, 'waterfall', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(12, 'waterfall', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(13, 'waterfall', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(14, 'waterfall', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(15, 'waterfall', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(16, 'waterfall', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(17, 'waterfall', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(18, 'waterfall', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(19, 'waterfall', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(20, 'waterfall', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(21, 'waterfall', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(22, 'waterfall', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(23, 'waterfall', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(24, 'waterfall', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(25, 'waterfall', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(26, 'waterfall', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(41, 'scrum', '原因分析与解决', 'support', 'CAR', '', '', '', 125, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(40, 'scrum', '度量分析', 'support', 'MA', '', '', '', 120, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(39, 'scrum', '配置管理', 'support', 'CM', '', '', '', 115, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(38, 'scrum', '质量保证', 'support', 'QA', '', '', '', 110, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(37, 'scrum', '客户验收', 'engineering', 'CA', '', '', '', 105, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(36, 'scrum', '系统测试', 'engineering', 'ST', '', '', '', 100, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(35, 'scrum', '实现与测试', 'engineering', 'EMBEDDED', '', '', '', 95, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(34, 'scrum', '设计开发', 'engineering', '', '', '', '', 90, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(33, 'scrum', '需求开发', 'engineering', 'RDM', '', '', '', 85, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(32, 'scrum', '量化项目管理', 'project', 'QPM', '', '', '', 80, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(31, 'scrum', '结项管理', 'project', 'PCM', '', '', '', 75, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(30, 'scrum', '风险管理', 'project', 'RSKM', '', '', '', 70, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(29, 'scrum', '项目监控', 'project', 'PMC', '', '', '', 65, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(28, 'scrum', '项目规划', 'project', 'PP', '', '', '', 60, 'admin', '2020-01-09 10:31:16', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(27, 'scrum', '立项管理', 'project', 'PIM', '', '', '', 55, 'admin', '2020-01-09 10:29:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0'),
(42, 'scrum', '决策分析', 'support', 'DAR', '', '', '', 130, 'admin', '2020-01-09 13:14:55', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '0');
REPLACE INTO `zt_activity` (`id`, `process`, `name`, `optional`, `content`, `assignedTo`, `status`, `createdBy`, `createdDate`, `editedBy`, `editedDate`, `assignedBy`, `assignedDate`, `order`, `deleted`) VALUES
(4,11,'立项调查,可行性分析,技术预研','yes','','','','admin','2020-01-09 10:49:34','','0000-00-00 00:00:00','','0000-00-00 00:00:00',20,'0'),
+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();
+2
View File
@@ -46,6 +46,8 @@
.minw-80px {min-width: 80px;}
.title-group.required:after {display: none;}
.title-group.required > .required:after {display: block; right: 29px; top: 5px;}
#titleBox.required:after{display: block; right: 29px; top: 5px;}
#priRequiredBox.required:after{display: block; right: -12px; top: 5px;}
.pri-selector > .btn {padding: 5px 8px !important; width: 100%;}
.pri-selector > .dropdown-menu {padding: 10px;}
+5 -5
View File
@@ -25,13 +25,13 @@
<thead>
<tr class='text-center'>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-module<?php echo strpos($config->testcase->create->requiredFields, 'module') ? ' required' : '';?>'><?php echo $lang->testcase->module;?></th>
<th class='c-module<?php echo strpos($config->testcase->create->requiredFields, 'module') !== false ? ' required' : '';?>'><?php echo $lang->testcase->module;?></th>
<th class='required'><?php echo $lang->testcase->title;?></th>
<th class='c-status required'><?php echo $lang->testcase->type;?></th>
<th class='c-status'><?php echo $lang->testcase->pri;?></th>
<th class='c-text'><?php echo $lang->testcase->precondition;?></th>
<th class='c-text'><?php echo $lang->testcase->keywords;?></th>
<th class='c-text'><?php echo $lang->testcase->stage;?></th>
<th class='c-status<?php echo strpos($config->testcase->create->requiredFields, 'pri') !== false ? ' required' : '';?>'><?php echo $lang->testcase->pri;?></th>
<th class='c-text<?php echo strpos($config->testcase->create->requiredFields, 'precondition') !== false ? ' required' : '';?>'><?php echo $lang->testcase->precondition;?></th>
<th class='c-text<?php echo strpos($config->testcase->create->requiredFields, 'keywords') !== false ? ' required' : '';?>'><?php echo $lang->testcase->keywords;?></th>
<th class='c-text<?php echo strpos($config->testcase->create->requiredFields, 'stage') !== false ? ' required' : '';?>'><?php echo $lang->testcase->stage;?></th>
</tr>
</thead>
<tbody>
+7 -6
View File
@@ -33,7 +33,7 @@
<?php echo html::select('lib', $libraries, $libID, "onchange='loadLibModules(this.value);' class='form-control chosen'");?>
</div>
</td>
<td style='padding-left:15px;'<?php echo strpos($config->testcase->create->requiredFields, 'module') ? ' class="required"' : '';?>>
<td style='padding-left:15px;'<?php echo strpos($config->testcase->create->requiredFields, 'module') !== false ? ' class="required"' : '';?>>
<div class='input-group' id='moduleIdBox'>
<span class="input-group-addon w-80px"><?php echo $lang->testcase->module?></span>
<?php
@@ -55,7 +55,7 @@
<th><?php echo $lang->testcase->type;?></th>
<td><?php echo html::select('type', $lang->testcase->typeList, $type, "class='form-control chosen'");?></td>
<?php if(strpos(",$showFields,", 'stage') !== false):?>
<td style='padding-left:15px'>
<td style='padding-left:15px'<?php echo strpos($config->testcase->create->requiredFields, 'stage') !== false ? ' class="required"' : '';?>>
<div class='input-group'>
<span class='input-group-addon w-80px'><?php echo $lang->testcase->stage?></span>
<?php echo html::select('stage[]', $lang->testcase->stageList, $stage, "class='form-control chosen' multiple='multiple'");?>
@@ -67,7 +67,7 @@
<th><?php echo $lang->testcase->title;?></th>
<td colspan='2'>
<div class="input-group title-group">
<div class="input-control has-icon-right">
<div id="titleBox" class="input-control has-icon-right">
<?php echo html::input('title', $caseTitle, "class='form-control'");?>
<div class="colorpicker">
<button type="button" class="btn btn-link dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><span class="color-bar"></span><i class="ic"></i></button>
@@ -101,7 +101,8 @@
<?php echo html::select('pri', (array)$priList, $pri, "class='form-control'");?>
<?php else: ?>
<?php ksort($priList);?>
<div class="input-group-btn pri-selector" data-type="pri">
<?php $hasPri = strpos($config->testcase->create->requiredFields, 'pri') !== false ? True : False;?>
<div <?php echo $hasPri ? "id='priRequiredBox'" : '';?> class="input-group-btn pri-selector <?php echo $hasPri ? 'required' : '';?>" data-type="pri">
<button type="button" class="btn dropdown-toggle br-0" data-toggle="dropdown">
<span class="pri-text"><span class="label-pri label-pri-<?php echo empty($pri) ? '0' : $pri?>" title="<?php echo $pri?>"><?php echo $pri?></span></span> &nbsp;<span class="caret"></span>
</button>
@@ -116,7 +117,7 @@
</tr>
<tr>
<th><?php echo $lang->testcase->precondition;?></th>
<td colspan='2'><?php echo html::textarea('precondition', $precondition, " rows='2' class='form-control'");?></td>
<td colspan='2' <?php echo strpos($config->testcase->create->requiredFields, 'precondition') !== false ? ' class="required"' : '';?>><?php echo html::textarea('precondition', $precondition, " rows='2' class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->testcase->steps;?></th>
@@ -189,7 +190,7 @@
<?php if(strpos(",$showFields,", ',keywords,') !== false):?>
<tr>
<th><?php echo $lang->testcase->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', '', "class='form-control'");?></td>
<td colspan='2' <?php echo strpos($config->testcase->create->requiredFields, 'keywords') !== false ? ' class="required"' : '';?>><?php echo html::input('keywords', '', "class='form-control'");?></td>
</tr>
<?php endif;?>
<tr>
+2 -1
View File
@@ -29,7 +29,8 @@ include 'chosen.html.php';
</div>
</div>
<?php if(isset($lang->{$app->tab}->menu->$activeMenu) and is_array($lang->{$app->tab}->menu->$activeMenu) and isset($lang->{$app->tab}->menu->{$activeMenu}['subMenu'])):?>
<div id='subHeader'>
<?php $subMenuClass = $app->tab == 'admin' ? 'admin-tab-menu' : '';?>
<div id='subHeader' class="<?php echo $subMenuClass?>">
<div class='container'>
<div id="pageNav" class='btn-toolbar'><?php if(isset($lang->modulePageNav)) echo $lang->modulePageNav;?></div>
<nav id='subNavbar'><?php common::printModuleMenu($activeMenu);?></nav>
+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';
+17 -6
View File
@@ -740,8 +740,6 @@ class programplanModel extends model
$datas[] = $plan;
}
$project = $this->loadModel('project')->getByID($projectID);
$productList = $this->loadModel('product')->getProductPairsByProject($projectID);
$totalPercent = 0;
$totalDevType = 0;
@@ -949,10 +947,6 @@ class programplanModel extends model
$this->setTreePath($stageID);
if($data->acl != 'open') $this->user->updateUserView($stageID, 'sprint');
$linkProducts = $project->division ? array(0 => $productID) : array_keys($productList);
$this->post->set('products', $linkProducts);
$this->execution->updateProducts($stageID);
/* Record version change information. */
$spec = new stdclass();
$spec->project = $stageID;
@@ -974,6 +968,23 @@ class programplanModel extends model
}
}
$linkProducts = array();
$linkBranches = array();
$productList = $this->loadModel('product')->getProducts($projectID);
if($project->division)
{
$linkProducts = array(0 => $productID);
$linkBranches = array(0 => $productList[$productID]->branches);
}
else
{
$linkProducts = array_keys($productList);
foreach($linkProducts as $index => $productID) $linkBranches[$index] = $productList[$productID]->branches;
}
$this->post->set('products', $linkProducts);
$this->post->set('branch', $linkBranches);
$this->execution->updateProducts($stageID);
/* If child plans has milestone, update parent plan set milestone eq 0 . */
if($parentID and $milestone) $this->dao->update(TABLE_PROJECT)->set('milestone')->eq(0)->where('id')->eq($parentID)->exec();
+13 -7
View File
@@ -2171,7 +2171,8 @@ class project extends control
$this->loadModel('program');
$this->loadModel('execution');
$project = $this->project->getById($projectID);
$project = $this->project->getById($projectID);
$executions = $this->execution->getPairs($projectID);
if(!empty($_POST))
{
@@ -2182,11 +2183,7 @@ class project extends control
}
$oldProducts = $this->product->getProducts($projectID);
if($project->multiple and $project->model != 'waterfall')
{
$executions = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($projectID)->fetchPairs('id');
$oldExecutionProducts = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->where('project')->in($executions)->fetchGroup('project', 'product');
}
if($project->multiple and $project->model != 'waterfall') $oldExecutionProducts = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->where('project')->in(array_keys($executions))->fetchGroup('project', 'product');
$this->project->updateProducts($projectID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
@@ -2203,6 +2200,15 @@ class project extends control
$diffProducts = array_merge(array_diff($oldProductIDs, $newProductIDs), array_diff($newProductIDs, $oldProductIDs));
if($diffProducts) $this->loadModel('action')->create('project', $projectID, 'Managed', '', !empty($_POST['products']) ? join(',', $_POST['products']) : '');
if(empty($project->division))
{
foreach(array_keys($executions) as $executionID)
{
$this->execution->updateProducts($executionID);
if($diffProducts) $this->loadModel('action')->create('execution', $executionID, 'Managed', '', implode(',', array_keys($newProducts)));
}
}
if($project->multiple and $project->model != 'waterfall')
{
$unlinkedProducts = array_diff($oldProductIDs, $newProductIDs);
@@ -2317,7 +2323,7 @@ class project extends control
$this->view->unmodifiableBranches = $unmodifiableBranches;
$this->view->unmodifiableMainBranches = $unmodifiableMainBranches;
$this->view->branchGroups = $branchGroups;
$this->view->executions = $this->execution->getPairs($projectID);
$this->view->executions = $executions;
$this->view->allBranches = $this->branch->getByProducts(array_keys($allProducts), 'ignoreNormal');
$this->view->allProducts = $allProducts;
+6
View File
@@ -1634,6 +1634,12 @@ class projectModel extends model
if(!dao::isError())
{
$this->updateProducts($projectID, $_POST['products']);
if(empty($oldProject->division))
{
$executions = $this->loadModel('execution')->getPairs($projectID);
foreach(array_keys($executions) as $executionID) $this->execution->updateProducts($executionID);
}
$this->file->updateObjectID($this->post->uid, $projectID, 'project');
$whitelist = explode(',', $project->whitelist);
+1 -1
View File
@@ -5511,7 +5511,7 @@ class storyModel extends model
$stories[$id]->title = $story->title;
$stories[$id]->cases = $this->loadModel('testcase')->getStoryCases($id);
$stories[$id]->bugs = $this->loadModel('bug')->getStoryBugs($id);
$stories[$id]->tasks = $this->loadModel('task')->getStoryTasks($id);
$stories[$id]->tasks = $this->loadModel('task')->getStoryTasks($id, 0, $projectID);
if($this->config->edition == 'max')
{
$stories[$id]->designs = $this->dao->select('id, name')->from(TABLE_DESIGN)
+3 -1
View File
@@ -2722,16 +2722,18 @@ class taskModel extends model
*
* @param int $storyID
* @param int $executionID
* @param int $projectID
* @access public
* @return array
*/
public function getStoryTasks($storyID, $executionID = 0)
public function getStoryTasks($storyID, $executionID = 0, $projectID = 0)
{
$tasks = $this->dao->select('id, parent, name, assignedTo, pri, status, estimate, consumed, closedReason, `left`')
->from(TABLE_TASK)
->where('story')->eq((int)$storyID)
->andWhere('deleted')->eq(0)
->beginIF($executionID)->andWhere('execution')->eq($executionID)->fi()
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->fetchAll('id');
$parents = array();
+2
View File
@@ -39,6 +39,8 @@
.title-group.required:after {display: none;}
.title-group.required > .required:after {display: block; right: 29px; top: 5px;}
#titleBox.required:after{display: block; right: 29px; top: 5px;}
#priRequiredBox.required:after{display: block; right: -12px; top: 5px;}
.pri-selector > .btn {padding: 5px 8px !important; width: 100%;}
.pri-selector > .dropdown-menu {padding: 10px;}
.stageBox {padding-left: 15px !important;}
+6
View File
@@ -36,11 +36,17 @@ $(function()
$searchInput.focus();
});
};
$(document).on('change', '#story', function()
{
if($(this).val() === 'showmore') showSearchModal();
});
$(document).on('click', '#priRequiredBox', function()
{
$('#priSelect').removeClass('required');
});
$(document).on('click', '#story_chosen .chosen-results > li.no-results', showSearchModal);
$searchStories.on('hide.zui.modal', function()
+5 -4
View File
@@ -111,7 +111,7 @@ foreach(explode(',', $config->testcase->create->requiredFields) as $field)
<th><?php echo $lang->testcase->title;?></th>
<td colspan='2'>
<div class="input-group title-group">
<div class="input-control has-icon-right">
<div id='titleBox' class="input-control has-icon-right">
<?php echo html::input('title', $caseTitle, "class='form-control'");?>
<div class="colorpicker">
<button type="button" class="btn btn-link dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><span class="color-bar"></span><i class="ic"></i></button>
@@ -145,11 +145,12 @@ foreach(explode(',', $config->testcase->create->requiredFields) as $field)
<?php echo html::select('pri', (array)$priList, $pri, "class='form-control priBox $hiddenPri'");?>
<?php else: ?>
<?php ksort($priList);?>
<div class="input-group-btn pri-selector priBox <?php echo $hiddenPri;?>" data-type="pri">
<button type="button" class="btn dropdown-toggle br-0" data-toggle="dropdown">
<?php $hasPri = strpos($config->testcase->create->requiredFields, 'pri') !== false ? True : False;?>
<div class="input-group-btn pri-selector <?php echo $hiddenPri;?>" data-type="pri">
<button <?php echo $hasPri ? "id='priRequiredBox'" : '';?> type="button" class="btn dropdown-toggle br-0 <?php echo $hasPri ? 'required' : '';?>" data-toggle="dropdown">
<span class="pri-text"><span class="label-pri label-pri-<?php echo empty($pri) ? '0' : $pri?>" title="<?php echo $pri?>"><?php echo $pri?></span></span> &nbsp;<span class="caret"></span>
</button>
<div class='dropdown-menu pull-right'>
<div class='dropdown-menu pull-right' id="priSelect">
<?php echo html::select('pri', (array)$priList, $pri, "class='form-control' data-provide='labelSelector' data-label-class='label-pri'");?>
</div>
</div>
+4
View File
@@ -122,6 +122,10 @@ class webhookModel extends model
{
$text = substr($data->markdown->content, 0, strpos($data->markdown->content, '(http'));
}
elseif(isset($data->text->content))
{
$text = substr($data->text->content, 0, strpos($data->text->content, '(http'));
}
elseif(isset($data->content))
{
$text = $data->content->text;
+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>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -1,2 +1,3 @@
<?php
$config->openMethods[] = 'setting.downloadxxd';
$config->openMethods[] = 'file.uploadchatavatar';