diff --git a/config/config.php b/config/config.php
index 083f134ff5..61f40b515f 100644
--- a/config/config.php
+++ b/config/config.php
@@ -165,8 +165,10 @@ $config->maxCount = 500;
$config->moreLinks = array();
/* 渠成平台设置。CNE Api settings. */
-$config->demoAccounts = ''; // 用于演示的账号列表,该账号安装的应用30钟后会自动删除。 In account list for demo, app instance of demo will be removed in 30 minutes.
-$config->demoAppLife = 30; // Demo安装的应用实例存续时长(分钟)。The minutes life of instance which demo account installed.
+$config->inQuickon = false;
+$config->inContainer = false;
+$config->demoAccounts = ''; // 用于演示的账号列表,该账号安装的应用30钟后会自动删除。 In account list for demo, app instance of demo will be removed in 30 minutes.
+$config->demoAppLife = 30; // Demo安装的应用实例存续时长(分钟)。The minutes life of instance which demo account installed.
$config->CNE = new stdclass();
$config->CNE->api = new stdclass();
$config->CNE->api->host = '';
diff --git a/db/update20.0.sql b/db/update20.0.sql
index 1e6f28e432..29ac6a8874 100644
--- a/db/update20.0.sql
+++ b/db/update20.0.sql
@@ -117,8 +117,6 @@ CREATE TABLE IF NOT EXISTS `zt_solution` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-REPLACE INTO `zt_space` (`id`, `name`,`k8space`,`owner`,`default`,`createdAt`) VALUES (1, 'default space', 'quickon-app', 'qadmin', 1, current_date());
-
CREATE TABLE IF NOT EXISTS `zt_session` (
`id` varchar(32) NOT NULL,
`data` mediumtext,
diff --git a/db/zentao.sql b/db/zentao.sql
index 7e8b32f101..24c200763b 100755
--- a/db/zentao.sql
+++ b/db/zentao.sql
@@ -14407,8 +14407,6 @@ CREATE TABLE IF NOT EXISTS `zt_solution` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-REPLACE INTO `zt_space` (`id`, `name`,`k8space`,`owner`,`default`,`createdAt`) VALUES (1, 'default space', 'quickon-app', 'qadmin', 1, current_date());
-
DROP FUNCTION IF EXISTS `get_monday`;
CREATE FUNCTION `get_monday`(day date) RETURNS date
begin if date_format(day, '%w') = 0 then return subdate(day, date_format(day, '%w') - 6)__DELIMITER__
diff --git a/module/admin/config.php b/module/admin/config.php
index 55803bd76c..9cd0560666 100755
--- a/module/admin/config.php
+++ b/module/admin/config.php
@@ -7,7 +7,7 @@ $config->admin->log->saveDays = 30;
if(!isset($config->safe)) $config->safe = new stdclass();
if(!isset($config->safe->weak)) $config->safe->weak = '123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123';
-$config->admin->menuGroup['system'] = array('custom|mode', 'backup', 'cron', 'action|trash', 'admin|xuanxuan', 'setting|xuanxuan', 'admin|license', 'admin|checkweak', 'admin|resetpwdsetting', 'admin|safe', 'custom|timezone', 'search|buildindex', 'admin|tableengine', 'ldap', 'custom|libreoffice', 'conference', 'client');
+$config->admin->menuGroup['system'] = array('custom|mode', 'backup', 'cron', 'action|trash', 'admin|xuanxuan', 'setting|xuanxuan', 'admin|license', 'admin|checkweak', 'admin|resetpwdsetting', 'admin|safe', 'custom|timezone', 'search|buildindex', 'admin|tableengine', 'ldap', 'custom|libreoffice', 'conference', 'client', 'system|browsebackup', 'system|restorebackup');
$config->admin->menuGroup['company'] = array('dept', 'company', 'user', 'group', 'tutorial');
$config->admin->menuGroup['switch'] = array('admin|setmodule');
$config->admin->menuGroup['model'] = array('auditcl', 'stage', 'design', 'cmcl', 'reviewcl', 'custom|required', 'custom|set', 'custom|flow', 'custom|code', 'custom|percent','custom|estimate', 'custom|hours', 'subject', 'process', 'activity', 'zoutput', 'classify', 'holiday', 'reviewsetting');
diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php
index d1071d3df1..466ee9b000 100644
--- a/module/admin/lang/menu.php
+++ b/module/admin/lang/menu.php
@@ -46,7 +46,6 @@ $lang->admin->menuList->convert['order'] = 50;
$lang->admin->menuList->platform['name'] = $lang->admin->menuSetting['platform']['name'];
$lang->admin->menuList->platform['desc'] = $lang->admin->menuSetting['platform']['desc'];
-$lang->admin->menuList->platform['link'] = 'system|browsebackup';
$lang->admin->menuList->platform['order'] = 55;
$lang->admin->menuList->system['subMenu']['mode'] = array('link' => "{$lang->custom->mode}|custom|mode|");
@@ -183,17 +182,17 @@ $lang->admin->menuList->dev['menuOrder']['20'] = 'editor';
$lang->admin->menuList->dev['menuOrder']['25'] = 'entry';
//$lang->admin->menuList->platform['subMenu']['dashboard'] = array('link' => "{$lang->dashboard}|system|dashboard|");
-$lang->admin->menuList->platform['subMenu']['plat'] = array('link' => "{$lang->devops->platform}|system|browsebackup|", 'subModule' => 'system');
+$lang->admin->menuList->platform['subMenu']['plat'] = array('link' => "{$lang->devops->platform}|system|dblist|", 'subModule' => 'system');
//$lang->admin->menuList->platform['subMenu']['environment'] = array('link' => "{$lang->devops->environment}|gitlab|browse|", 'subModule' => 'gitlab,jenkins,sonarqube,gitea,gogs', 'alias' => 'create,edit,import');
$lang->admin->menuList->platform['subMenu']['resource'] = array('link' => "{$lang->devops->resource}|host|browse|", 'subModule' => 'host,account,serverroom,ops,tree');
$lang->admin->menuList->platform['subMenu']['setrules'] = array('link' => "{$lang->devops->rules}|repo|setrules|");
-$lang->admin->menuList->platform['tabMenu']['plat']['backup'] = array('link' => "{$lang->backup->common}|system|browsebackup|");
+//$lang->admin->menuList->platform['tabMenu']['plat']['backup'] = array('link' => "{$lang->backup->common}|system|browsebackup|");
$lang->admin->menuList->platform['tabMenu']['plat']['dblist'] = array('link' => "{$lang->devops->dblist}|system|dblist|");
$lang->admin->menuList->platform['tabMenu']['plat']['domain'] = array('link' => "{$lang->devops->domain}|system|configdomain|", 'alias' => 'editdomain,domainview');
$lang->admin->menuList->platform['tabMenu']['plat']['oss'] = array('link' => "{$lang->devops->oss}|system|ossview|");
-$lang->admin->menuList->platform['tabMenu']['menuOrder']['plat']['5'] = 'backup';
+//$lang->admin->menuList->platform['tabMenu']['menuOrder']['plat']['5'] = 'backup';
$lang->admin->menuList->platform['tabMenu']['menuOrder']['plat']['10'] = 'dblist';
$lang->admin->menuList->platform['tabMenu']['menuOrder']['plat']['15'] = 'domain';
$lang->admin->menuList->platform['tabMenu']['menuOrder']['plat']['20'] = 'oss';
@@ -285,3 +284,8 @@ if($config->vision == 'lite')
$lang->admin->menuList->feature['menuOrder']['15'] = 'project';
}
+
+if($config->inQuickon)
+{
+ $lang->admin->menuList->system['subMenu']['backup'] = array('link' => "{$lang->backup->common}|system|browsebackup|", 'alias' => 'restorebackup');
+}
diff --git a/module/cne/model.php b/module/cne/model.php
index 81d5b68774..493286c8c1 100644
--- a/module/cne/model.php
+++ b/module/cne/model.php
@@ -1202,4 +1202,85 @@ class cneModel extends model
return $this->error;
}
+
+ /**
+ * 获取备份平台列表。
+ * Get backup platform list.
+ *
+ * @access public
+ * @return object
+ */
+ public function getBackupPlatformList(): object
+ {
+ $apiUrl = "/api/cne/platform/backups";
+ return $this->apiGet($apiUrl, array(), $this->config->CNE->api->headers);
+ }
+
+ /**
+ * 备份平台和应用。
+ * Backup platform and apps.
+ *
+ * @param array $apps
+ * @access public
+ * @return object
+ */
+ public function backupPlatform(array $apps = array()): object
+ {
+ $apiParams = new stdclass();
+ $apiParams->apps = $apps;
+
+ $apiUrl = "/api/cne/platform/backup";
+ return $this->apiPost($apiUrl, $apiParams, $this->config->CNE->api->headers);
+ }
+
+ /**
+ * 获取备份平台状态。
+ * Get backup platfrom status.
+ *
+ * @param string $name
+ * @access public
+ * @return object
+ */
+ public function backupPlatformStatus(string $name): object
+ {
+ $apiParams = new stdclass();
+ $apiParams->name = $name;
+
+ $apiUrl = "/api/cne/platform/backup/status";
+ return $this->apiGet($apiUrl, $apiParams, $this->config->CNE->api->headers);
+ }
+
+ /**
+ * 还原平台和应用。
+ * Restroe platform and apps.
+ *
+ * @param array $apps
+ * @access public
+ * @return object
+ */
+ public function restorePlatform(string $name): object
+ {
+ $apiParams = new stdclass();
+ $apiParams->backup_set_name = $name;
+
+ $apiUrl = "/api/cne/platform/restore";
+ return $this->apiPost($apiUrl, $apiParams, $this->config->CNE->api->headers);
+ }
+
+ /**
+ * 获取备份平台状态。
+ * Get backup platfrom status.
+ *
+ * @param string $name
+ * @access public
+ * @return object
+ */
+ public function restorePlatformStatus(string $name): object
+ {
+ $apiParams = new stdclass();
+ $apiParams->name = $name;
+
+ $apiUrl = "/api/cne/platform/restore/status";
+ return $this->apiGet($apiUrl, $apiParams, $this->config->CNE->api->headers);
+ }
}
diff --git a/module/sonarqube/control.php b/module/sonarqube/control.php
index 3dcb9b5d4a..dae6dd7320 100644
--- a/module/sonarqube/control.php
+++ b/module/sonarqube/control.php
@@ -140,7 +140,7 @@ class sonarqube extends control
->skipSpecial('url,token,account,password')
->remove('token,appType')
->get();
- $this->checkToken($sonarqube);
+ $this->checkToken($sonarqube, 0);
$sonarqubeID = $this->loadModel('pipeline')->create($sonarqube);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
@@ -160,9 +160,8 @@ class sonarqube extends control
* @access protected
* @return void
*/
- protected function checkToken(int $sonarqubeID)
+ protected function checkToken(object $sonarqube, int $sonarqubeID = 0)
{
- $sonarqube = fixer::input('post')->trim('url,token,account,password')->get();
$this->dao->update('sonarqube')->data($sonarqube)
->batchCheck(empty($sonarqubeID) ? $this->config->sonarqube->create->requiredFields : $this->config->sonarqube->edit->requiredFields, 'notempty')
->batchCheck("url", 'URL');
diff --git a/module/space/control.php b/module/space/control.php
index c83c86a240..0c6d20762a 100644
--- a/module/space/control.php
+++ b/module/space/control.php
@@ -106,10 +106,13 @@ class space extends control
$this->app->loadLang('jenkins');
$this->loadModel('cne');
- $pagedApps = $this->loadModel('store')->searchApps('', '', array(), 1, 10000);
- $apps = array();
+ $pagedApps = $this->loadModel('store')->searchApps('', '', array(), 1, 10000);
+ $apps = array();
+ $defaultApp = '';
foreach($pagedApps->apps as $app)
{
+ if(!$appID and $app->alias == 'GitLab') $defaultApp = $app->id;
+
$apps[$app->id] = $app->alias;
}
@@ -119,6 +122,7 @@ class space extends control
$this->view->apps = $apps;
$this->view->appID = $appID;
+ $this->view->defaultApp = $defaultApp;
$this->view->pgList = $pgList;
$this->view->mysqlList = $mysqlList;
$this->view->versionList = $versionList;
diff --git a/module/space/js/createapplication.ui.js b/module/space/js/createapplication.ui.js
index 2a50b7f23f..a0c90ffd43 100644
--- a/module/space/js/createapplication.ui.js
+++ b/module/space/js/createapplication.ui.js
@@ -70,28 +70,29 @@ function onChangeAppType(event)
}
}
-function onChangeStoreAppType()
+function onChangeStoreAppType(event)
{
- var storeApp = $('[name=storeAppType]').val();
- if(!storeApp)
+ if(typeof(event) == 'undefined')
{
- for(id in apps)
- {
- storeApp = id;
- break;
- }
+ var storeApp = defaultApp;
}
+ else
+ {
+ var storeApp = $('[name=storeAppType]').val();
+ }
+
$('#createStoreAppForm').attr('action', $.createLink('instance', 'install', 'appID=' + storeApp));
var externalApps = ['GitLab', 'Gitea', 'Gogs', 'Jenkins', 'SonarQube'];
var storeAppName = apps[storeApp];
+
if(externalApps.indexOf(storeAppName) !== -1)
{
- $('#storetypeexternal').prop('disabled', false);
+ $('#createStoreAppForm input[name=type][value=external]').prop('disabled', false);
}
else
{
- $('#storetypeexternal').prop('disabled', true);
+ $('#createStoreAppForm input[name=type][value=external]').prop('disabled', true);
}
toggleLoading('#app_version', true);
diff --git a/module/space/lang/en.php b/module/space/lang/en.php
index c241b37134..eaef92d3f3 100644
--- a/module/space/lang/en.php
+++ b/module/space/lang/en.php
@@ -1,9 +1,27 @@
space->status = 'Status';
+$lang->space->noApps = 'No service';
+$lang->space->defaultSpace = 'Default space';
+$lang->space->systemSpace = 'System space';
+$lang->space->searchInstance = 'Search Services';
+$lang->space->upgrade = 'Upgrade';
+$lang->space->install = 'Add an application';
+$lang->space->createdBy = 'Creator';
+$lang->space->createdAt = 'Creation time';
$lang->space->handConfig = 'Manual configuration';
$lang->space->addType = 'Add method';
+$lang->space->instanceType = 'Instance type';
-$lang->space->appType['Gitlab'] = 'Gitlab';
+$lang->space->byList = 'List';
+$lang->space->byCard = 'Card';
+
+$lang->space->featureBar['browse']['all'] = 'All';
+$lang->space->featureBar['browse']['running'] = 'Running';
+$lang->space->featureBar['browse']['stopped'] = 'Stopped';
+$lang->space->featureBar['browse']['abnormal'] = 'Abnormal';
+
+$lang->space->appType['GitLab'] = 'GitLab';
$lang->space->appType['Gitea'] = 'Gitea';
$lang->space->appType['Gogs'] = 'Gogs';
$lang->space->appType['Jenkins'] = 'Jenkins';
-$lang->space->appType['Sonarqube'] = 'Sonarqube';
+$lang->space->appType['SonarQube'] = 'SonarQube';
diff --git a/module/space/lang/zh-cn.php b/module/space/lang/zh-cn.php
index 3ecf410f58..34a74b3181 100644
--- a/module/space/lang/zh-cn.php
+++ b/module/space/lang/zh-cn.php
@@ -19,13 +19,12 @@ $lang->space->byList = '列表';
$lang->space->byCard = '卡片';
$lang->space->featureBar['browse']['all'] = '全部';
-//$lang->space->filterList['toBeUpdated'] = '待更新';
$lang->space->featureBar['browse']['running'] = '运行中';
$lang->space->featureBar['browse']['stopped'] = '已停止';
$lang->space->featureBar['browse']['abnormal'] = '异常';
-$lang->space->appType['Gitlab'] = 'Gitlab';
+$lang->space->appType['GitLab'] = 'GitLab';
$lang->space->appType['Gitea'] = 'Gitea';
$lang->space->appType['Gogs'] = 'Gogs';
$lang->space->appType['Jenkins'] = 'Jenkins';
-$lang->space->appType['Sonarqube'] = 'Sonarqube';
+$lang->space->appType['SonarQube'] = 'SonarQube';
diff --git a/module/space/ui/createapplication.html.php b/module/space/ui/createapplication.html.php
index 48d19cf093..c2720c3a95 100644
--- a/module/space/ui/createapplication.html.php
+++ b/module/space/ui/createapplication.html.php
@@ -19,6 +19,7 @@ jsVar('jenkinsPasswordTips', $lang->jenkins->tips);
jsVar('apps', $apps);
jsVar('mysqlList', $mysqlList);
jsVar('pgList', $pgList);
+jsVar('defaultApp', $defaultApp);
$showVersion = getenv('ALLOW_SELECT_VERSION') && (strtolower(getenv('ALLOW_SELECT_VERSION')) == 'true' || strtolower(getenv('ALLOW_SELECT_VERSION')) == '1');
$dbTypeItems = array();
@@ -26,82 +27,7 @@ foreach($lang->instance->dbTypes as $type => $db) $dbTypeItems[] = array('text'
formPanel
(
- setClass('externalPanel' . (!$appID ? '' : ' hidden')),
- set::id('createAppForm'),
- set::title($lang->space->install),
- set::url($this->createLink('gitlab', 'create')),
- formGroup
- (
- set::width('1/2'),
- set::label($lang->app->common),
- set::name('appType'),
- set::items($lang->space->appType),
- set::required(true),
- on::change('onChangeAppType'),
- ),
- formGroup
- (
- set::label($lang->space->addType),
- set::name('type'),
- set::value('external'),
- set::control('radioListInline'),
- set::items(array(array('text' => $lang->store->common, 'value' => 'store'), array('text' => $lang->space->handConfig, 'value' => 'external'))),
- set::required(true),
- on::change('onChangeType'),
- ),
- formGroup
- (
- set::width('1/2'),
- set::label($lang->gitlab->name),
- set::name('name'),
- set::required(true),
- ),
- formGroup
- (
- set::width('2/3'),
- set::label($lang->gitlab->url),
- set::name('url'),
- set::required(true),
- set::placeholder($lang->gitlab->placeholder->url)
- ),
- formRow
- (
- setClass('jenkins sonarqube hidden'),
- formGroup
- (
- set::width('1/2'),
- set::label($lang->user->account),
- set::name('account'),
- set::required(true),
- ),
- ),
- formRow
- (
- setClass('token'),
- formGroup
- (
- set::width('1/2'),
- set::label($lang->gitlab->token),
- set::name('token'),
- set::placeholder($lang->gitlab->placeholder->token),
- set::required(true),
- ),
- ),
- formRow
- (
- setClass('jenkins sonarqube password hidden'),
- formGroup
- (
- set::width('1/2'),
- set::label($lang->user->password),
- set::name('password'),
- ),
- ),
-);
-
-formPanel
-(
- setClass('storePanel' . ($appID ? '' : ' hidden')),
+ setClass('storePanel'),
set::id('createStoreAppForm'),
set::title($lang->space->install),
$appID ? set::submitBtnText($lang->instance->install) : null,
@@ -111,7 +37,7 @@ formPanel
setStyle('display', $appID ? 'block' : 'none'),
formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->instance->name),
set::name('customName'),
set::control('input'),
@@ -124,11 +50,11 @@ formPanel
setStyle('display', $appID ? 'none' : 'block'),
formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->app->common),
set::name('storeAppType'),
set::items($apps),
- set::value($appID),
+ set::value($appID ? $appID : $defaultApp),
set::disabled(!!$appID),
set::required(true),
on::change('onChangeStoreAppType'),
@@ -151,7 +77,7 @@ formPanel
),
$showVersion ? formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->instance->version),
set::name('version'),
set::required(true),
@@ -159,7 +85,7 @@ formPanel
set::items($versionList)
) : formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->instance->version),
set::name('app_version'),
set::required(true),
@@ -174,7 +100,7 @@ formPanel
(
formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->instance->domain),
set::required(true),
inputGroup
@@ -216,7 +142,7 @@ formPanel
setClass('dbType dbService'),
formGroup
(
- set::width('1/2'),
+ set::width('2/3'),
set::label($lang->space->instanceType),
set::name('dbService'),
set::items(array()),
@@ -225,4 +151,79 @@ formPanel
),
);
+formPanel
+(
+ setClass('externalPanel hidden'),
+ set::id('createAppForm'),
+ set::title($lang->space->install),
+ set::url($this->createLink('gitlab', 'create')),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->app->common),
+ set::name('appType'),
+ set::items($lang->space->appType),
+ set::required(true),
+ on::change('onChangeAppType'),
+ ),
+ formGroup
+ (
+ set::label($lang->space->addType),
+ set::name('type'),
+ set::value('external'),
+ set::control('radioListInline'),
+ set::items(array(array('text' => $lang->store->common, 'value' => 'store'), array('text' => $lang->space->handConfig, 'value' => 'external'))),
+ set::required(true),
+ on::change('onChangeType'),
+ ),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->gitlab->name),
+ set::name('name'),
+ set::required(true),
+ ),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->gitlab->url),
+ set::name('url'),
+ set::required(true),
+ set::placeholder($lang->gitlab->placeholder->url)
+ ),
+ formRow
+ (
+ setClass('jenkins sonarqube hidden'),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->user->account),
+ set::name('account'),
+ set::required(true),
+ ),
+ ),
+ formRow
+ (
+ setClass('token'),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->gitlab->token),
+ set::name('token'),
+ set::placeholder($lang->gitlab->placeholder->token),
+ set::required(true),
+ ),
+ ),
+ formRow
+ (
+ setClass('jenkins sonarqube password hidden'),
+ formGroup
+ (
+ set::width('2/3'),
+ set::label($lang->user->password),
+ set::name('password'),
+ ),
+ ),
+);
+
render();
diff --git a/module/system/config/dtable.php b/module/system/config/dtable.php
index d1b47252f1..57b1135c94 100644
--- a/module/system/config/dtable.php
+++ b/module/system/config/dtable.php
@@ -31,9 +31,13 @@ $config->system->dtable->backup = new stdclass();
$config->system->dtable->backup->fieldList['time']['title'] = $lang->backup->time;
$config->system->dtable->backup->fieldList['time']['type'] = 'datetime';
-$config->system->dtable->backup->fieldList['backupPerson']['title'] = $lang->system->backup->backupPerson;
-
$config->system->dtable->backup->fieldList['type']['title'] = $lang->system->backup->type;
+$config->system->dtable->backup->fieldList['type']['map'] = $lang->system->backup->typeList;
+
+$config->system->dtable->backup->fieldList['status']['title'] = $lang->backup->status;
+
+$config->system->dtable->backup->fieldList['comment']['title'] = $lang->comment;
+$config->system->dtable->backup->fieldList['comment']['type'] = 'html';
$config->system->dtable->backup->fieldList['actions']['name'] = 'actions';
$config->system->dtable->backup->fieldList['actions']['title'] = $lang->actions;
@@ -42,10 +46,10 @@ $config->system->dtable->backup->fieldList['actions']['menu'] = array('restore'
$config->system->dtable->backup->fieldList['actions']['list']['restore']['icon'] = 'history';
$config->system->dtable->backup->fieldList['actions']['list']['restore']['hint'] = $lang->backup->restore;
-$config->system->dtable->backup->fieldList['actions']['list']['restore']['url'] = array('module' => 'backup', 'method' => 'restore', 'params' => 'time={time}');
-$config->system->dtable->backup->fieldList['actions']['list']['restore']['data-confirm'] = $lang->system->backup->confirmDelete;
+$config->system->dtable->backup->fieldList['actions']['list']['restore']['url'] = array('module' => 'system', 'method' => 'restoreBackup', 'params' => 'name={name}');
+$config->system->dtable->backup->fieldList['actions']['list']['restore']['data-confirm'] = $lang->system->backup->confirmRestore;
$config->system->dtable->backup->fieldList['actions']['list']['delete']['icon'] = 'trash';
$config->system->dtable->backup->fieldList['actions']['list']['delete']['hint'] = $lang->delete;
-$config->system->dtable->backup->fieldList['actions']['list']['delete']['url'] = array('module' => 'backup', 'method' => 'delete', 'params' => 'time={time}');
-$config->system->dtable->backup->fieldList['actions']['list']['delete']['data-confirm'] = $lang->system->backup->confirmRestore;
+$config->system->dtable->backup->fieldList['actions']['list']['delete']['url'] = array('module' => 'system', 'method' => 'deleteBackup', 'params' => 'name={name}');
+$config->system->dtable->backup->fieldList['actions']['list']['delete']['data-confirm'] = $lang->system->backup->confirmDelete;
diff --git a/module/system/control.php b/module/system/control.php
index 9ffe0cb106..e8913b78d9 100644
--- a/module/system/control.php
+++ b/module/system/control.php
@@ -572,31 +572,44 @@ class system extends control
$this->display();
}
+ /**
+ * 平台备份列表。
+ * Browse platform backup.
+ *
+ * @access public
+ * @return viod
+ */
public function browseBackup()
{
+ $this->loadModel('repo');
$backups = array();
- if(empty($this->view->error))
+
+ $actions = $this->loadModel('action')->getList('platformbackup', 0);
+ foreach($actions as $id => $action)
{
- $sqlFiles = glob("{$this->backupPath}*.sql*");
- if(!empty($sqlFiles))
+ if($action->action != 'backupcommented')
{
- foreach($sqlFiles as $file)
- {
- $fileName = basename($file);
- $backupFile = new stdclass();
- $backupFile->time = filemtime($file);
- $backupFile->name = substr($fileName, 0, strpos($fileName, '.'));
- $backupFile->sqlSummary = $this->system->getSQLSummary($file);
- $backupFile->files[$file] = $this->backup->getBackupSummary($file);
+ unset($actions[$id]);
+ continue;
+ }
- $fileBackup = $this->backup->getBackupFile($backupFile->name, 'file');
- if($fileBackup) $backupFile->files[$fileBackup] = $this->backup->getBackupSummary($fileBackup);
+ $actions[$action->extra] = $action;
+ unset($actions[$id]);
+ }
- $codeBackup = $this->backup->getBackupFile($backupFile->name, 'code');
- if($codeBackup) $backupFile->files[$codeBackup] = $this->backup->getBackupSummary($codeBackup);
+ $result = $this->loadModel('cne')->getBackupPlatformList();
+ if($result && $result->data)
+ {
+ foreach($result->data as $data)
+ {
+ $backup = new stdclass();
+ $backup->time = date("Y-m-d H:i:s", $data->create_time);
+ $backup->status = zget($this->lang->system->backup->statusList, $data->status);
+ $backup->name = $this->repo->encodePath($data->name);
+ $backup->type = (!empty($actions[$data->name]) && $actions[$data->name]->objectType == 'platformbackup') ? 'manual' : '';
+ $backup->comment = !empty($actions[$data->name]) ? nl2br($actions[$data->name]->comment) : '';
- $backups[$backupFile->name] = $backupFile;
- }
+ $backups[$data->create_time] = $backup;
}
}
krsort($backups);
@@ -607,6 +620,124 @@ class system extends control
$this->display();
}
+ /**
+ * Backup platform and apps.
+ *
+ * @access public
+ * @return viod
+ */
+ public function backupPlatform()
+ {
+ if($_POST)
+ {
+ session_write_close();
+
+ $space = $this->loadModel('space')->defaultSpace($this->app->user->account);
+ $instances = $this->space->getSpaceInstances($space->id);
+ $apps = array();
+ foreach($instances as $instance)
+ {
+ $app = new stdclass();
+ $app->name = $instance->k8name;
+ $app->namespace = $space->k8space;
+
+ $apps[] = $app;
+ }
+
+ $result = $this->loadModel('cne')->backupPlatform($apps);
+ if($result && $result->code == 200)
+ {
+ $this->loadModel('action')->create('platformBackup', '0', 'backupCommented', $this->post->comment, $result->data->name);
+ return $this->send(array('result' => 'success', 'name' => $result->data->name));
+ }
+ else
+ {
+ return $this->send(array('result' => 'failed', 'message' => $result->message));
+ }
+ }
+
+ $this->display();
+ }
+
+ /**
+ * 还原平台备份。
+ * Restore platform backup.
+ *
+ * @param string $backupName
+ * @access public
+ * @return viod
+ */
+ public function restoreBackup(string $backupName)
+ {
+ $backupName = $this->loadModel('repo')->decodePath($backupName);
+
+ $error = '';
+ $result = $this->loadModel('cne')->restorePlatform($backupName);
+ if($result && $result->code == 200)
+ {
+ $restoreName = $result->data->name;
+ $this->loadModel('action')->create('platformBackup', '0', 'restore', '', $restoreName);
+ }
+ else
+ {
+ $error = $result->message;
+ }
+
+ $this->view->error = $error;
+ $this->view->restoreName = $restoreName;
+ $this->display();
+ }
+
+ /**
+ * Ajax 获取备份进度。
+ * Ajax get backup progress.
+ *
+ * @access public
+ * @return viod
+ */
+ public function ajaxGetBackupProgress()
+ {
+ session_write_close();
+
+ $result = $this->loadModel('cne')->backupPlatformStatus($this->post->name);
+ if($result && $result->code == 200)
+ {
+ $status = $result->data->status;
+ if($status == 'completed') return $this->send(array('result' => 'success', 'message' => $this->lang->backup->success->backup, 'closeModal' => true, 'load' => inlink('browseBackup')));
+ if($status == 'pending' || $status == 'inprogress') return $this->send(array('result' => 'progress', 'text' => sprintf($this->lang->system->backup->progress, $result->data->completed, $result->data->total)));
+ if($status == 'failed') return $this->send(array('result' => 'failed', 'message' => $this->lang->system->backup->error->backupFail, 'closeModal' => true));
+ }
+ else
+ {
+ return $this->send(array('result' => 'failed', 'message' => $result->message, 'closeModal' => true));
+ }
+ }
+
+ /**
+ * Ajax 获取还原进度。
+ * Ajax get restore progress.
+ *
+ * @access public
+ * @return viod
+ */
+ public function ajaxGetRestoreProgress()
+ {
+ session_write_close();
+
+ $result = $this->loadModel('cne')->restorePlatformStatus($this->post->name);
+ if($result && $result->code == 200)
+ {
+ $status = $result->data->status;
+ if($status == 'completed') return $this->send(array('result' => 'success', 'message' => $this->lang->backup->success->restore, 'load' => inlink('browseBackup')));
+ if($status == 'pending' || $status == 'inprogress') return $this->send(array('result' => 'progress', 'text' => sprintf($this->lang->system->backup->progressStore, $result->data->completed, $result->data->total)));
+ if($status == 'failed') return $this->send(array('result' => 'failed', 'message' => $this->lang->system->backup->error->backupFail, 'load' => inlink('browseBackup')));
+ }
+ else
+ {
+ return $this->send(array('result' => 'failed', 'message' => $result->message, 'load' => inlink('browseBackup')));
+ }
+ }
+
/**
* Verify SMTP account by ajax.
*
diff --git a/module/system/js/backupplatform.ui.js b/module/system/js/backupplatform.ui.js
new file mode 100644
index 0000000000..23b65c3aba
--- /dev/null
+++ b/module/system/js/backupplatform.ui.js
@@ -0,0 +1,57 @@
+var backupInterval;
+var backupName;
+
+/**
+ * Start backup.
+ *
+ * @access public
+ * @return viod
+ */
+function startBackup()
+{
+ const form = new FormData($("#backupForm")[0]);
+
+ $.ajaxSubmit({
+ url: $.createLink('system', 'backupPlatform'),
+ data: form,
+ onComplete: function(response)
+ {
+ if(response.result == 'success')
+ {
+ $('.modal-content .panel-body').html(waitting);
+ backupName = response.name;
+ backupInterval = setInterval(checkBackup, 2000);
+ }
+ else
+ {
+ zui.Modal.alert(response.message);
+ }
+ },
+ });
+}
+
+/**
+ * Check backup progress.
+ *
+ * @access public
+ * @return viod
+ */
+function checkBackup()
+{
+ $.ajaxSubmit({
+ url: $.createLink('system', 'ajaxGetBackupProgress'),
+ data: {'name': backupName},
+ onComplete: function(response)
+ {
+ if(response.result == 'progress')
+ {
+ $('.modal-content .panel-body').html(response.text);
+ }
+ else
+ {
+ clearInterval(backupInterval);
+ if(response.result == 'failed') zui.Modal.alert(response.message);
+ }
+ },
+ });
+}
diff --git a/module/system/js/restorebackup.ui.js b/module/system/js/restorebackup.ui.js
new file mode 100644
index 0000000000..5d0d28136f
--- /dev/null
+++ b/module/system/js/restorebackup.ui.js
@@ -0,0 +1,35 @@
+/**
+ * Check restore progress.
+ *
+ * @access public
+ * @return viod
+ */
+function checkRestore()
+{
+ $.ajaxSubmit({
+ url: $.createLink('system', 'ajaxGetRestoreProgress'),
+ data: {'name': restoreName},
+ onComplete: function(response)
+ {
+ if(response.result == 'progress')
+ {
+ $('div.restoreProgress').html(response.text);
+ }
+ else
+ {
+ clearInterval(restoreInterval);
+ if(response.result == 'failed') zui.Modal.alert(response.message);
+ }
+ },
+ });
+}
+
+if(error)
+{
+ zui.Modal.alert(error);
+ openUrl($.createLink('system', 'browseBackup'));
+}
+else
+{
+ var restoreInterval = setInterval(checkRestore, 2000);
+}
diff --git a/module/system/lang/en.php b/module/system/lang/en.php
index 9901ec3342..94d6058569 100644
--- a/module/system/lang/en.php
+++ b/module/system/lang/en.php
@@ -210,6 +210,11 @@ $lang->system->backup->rollback = 'Rollback';
$lang->system->backup->restart = 'Restart';
$lang->system->backup->delete = 'Delte';
+$lang->system->backup->statusList['pending'] = 'Waiting';
+$lang->system->backup->statusList['inprogress'] = 'In progress';
+$lang->system->backup->statusList['completed'] = 'Compelete';
+$lang->system->backup->statusList['failed'] = 'Fail';
+
$lang->system->backup->restoreProgress['doing'] = 'Doing';
$lang->system->backup->restoreProgress['done'] = 'Done';
@@ -217,12 +222,14 @@ $lang->system->backup->typeList['manual'] = 'Manual backup';
$lang->system->backup->typeList['upgrade'] = 'Automatic backup before upgrade';
$lang->system->backup->typeList['restore'] = 'Automatic backup before rollback';
-$lang->system->backup->waitting = 'In progress,please wait...';
+$lang->system->backup->waitting = 'Backup is in progress, please wait...';
+$lang->system->backup->waittingStore = 'Restoring app data, please wait...';
+$lang->system->backup->progress = 'Backup in progress(%d/%d)';
$lang->system->backup->progressSQL = 'In backup,%s has been backed up';
$lang->system->backup->progressAttach = 'There are a total of %s files in the backup, and %s files have already been backed up';
$lang->system->backup->progressCode = 'There are a total of %s files in the backup, and %s files have already been backed up';
$lang->system->backup->confirmDelete = 'Do you want to delte the backup';
-$lang->system->backup->confirmRestore = 'Please confirm whether to roallback?';
+$lang->system->backup->confirmRestore = 'A restart is required during the platform restore process, which will cause all your current operations to be interrupted and cannot be restored. Are you sure you want to continue?';
$lang->system->backup->holdDays = 'Backup has been retained for the last %s days';
$lang->system->backup->copiedFail = 'Files that failed to copy:';
$lang->system->backup->restoreTip = 'The restore function only restores the database.';
@@ -239,7 +246,8 @@ $lang->system->backup->success->upgrade = 'Upgrade successful!';
$lang->system->backup->success->degrade = 'Successfully downgraded!';
$lang->system->backup->error = new stdclass();
-
+$lang->system->backup->error->backupFail = "Backup failed!";
+$lang->system->backup->error->restoreFail = "Restore failed!";
$lang->system->backup->error->upgradeFail = "Upgrade failed!";
$lang->system->backup->error->upgradeOvertime = "Upgrade timed out!";
$lang->system->backup->error->degradeFail = "Downgrade failed!";
diff --git a/module/system/lang/zh-cn.php b/module/system/lang/zh-cn.php
index be6a14cc69..6116c185de 100644
--- a/module/system/lang/zh-cn.php
+++ b/module/system/lang/zh-cn.php
@@ -212,6 +212,11 @@ $lang->system->backup->rollback = '回滚';
$lang->system->backup->restart = '重启';
$lang->system->backup->delete = '删除';
+$lang->system->backup->statusList['pending'] = '等待中';
+$lang->system->backup->statusList['inprogress'] = '进行中';
+$lang->system->backup->statusList['completed'] = '完成';
+$lang->system->backup->statusList['failed'] = '失败';
+
$lang->system->backup->restoreProgress['doing'] = '进行中';
$lang->system->backup->restoreProgress['done'] = '完成';
@@ -219,12 +224,15 @@ $lang->system->backup->typeList['manual'] = '手动备份';
$lang->system->backup->typeList['upgrade'] = '升级前自动备份';
$lang->system->backup->typeList['restore'] = '回滚前自动备份';
-$lang->system->backup->waitting = '正在进行中,请稍候...';
+$lang->system->backup->waitting = '备份正在进行中,请稍候...';
+$lang->system->backup->waittingStore = '正在还原应用数据,请稍候...';
+$lang->system->backup->progress = '备份中,进度(%d/%d)';
+$lang->system->backup->progressStore = '还原中,进度(%d/%d)';
$lang->system->backup->progressSQL = '备份中,已备份%s';
$lang->system->backup->progressAttach = '备份中,共有%s个文件,已经备份%s个';
$lang->system->backup->progressCode = '代码备份中,共有%s个文件,已经备份%s个';
$lang->system->backup->confirmDelete = '是否删除该备份?';
-$lang->system->backup->confirmRestore = '请确认是否回滚?';
+$lang->system->backup->confirmRestore = '平台还原过程中需要重启,这将导致您当前的所有操作中断并且无法恢复,您确定要继续吗?';
$lang->system->backup->holdDays = '备份保留最近 %s 天';
$lang->system->backup->copiedFail = '复制失败的文件:';
$lang->system->backup->restoreTip = '还原功能只还原数据库。';
@@ -242,6 +250,8 @@ $lang->system->backup->success->degrade = '降级成功!';
$lang->system->backup->error = new stdclass();
+$lang->system->backup->error->backupFail = "备份失败!";
+$lang->system->backup->error->restoreFail = "还原失败!";
$lang->system->backup->error->upgradeFail = "升级失败!";
$lang->system->backup->error->upgradeOvertime = "升级超时!";
$lang->system->backup->error->degradeFail = "降级失败!";
diff --git a/module/system/ui/backupplatform.html.php b/module/system/ui/backupplatform.html.php
new file mode 100644
index 0000000000..909f087609
--- /dev/null
+++ b/module/system/ui/backupplatform.html.php
@@ -0,0 +1,33 @@
+
+ * @package system
+ * @link https://www.zentao.net
+ */
+namespace zin;
+
+jsVar('waitting', $lang->system->backup->waitting);
+
+modalHeader(set::title($lang->system->backup->backup));
+formPanel
+(
+ on::click('#startBackup', 'startBackup'),
+ set::id('backupForm'),
+ formGroup
+ (
+ set::label($lang->comment),
+ set::name('comment'),
+ set::control('textarea'),
+ set::rows('6'),
+ ),
+ set::actions(array
+ (
+ array('text' => $lang->confirm, 'id' => 'startBackup', 'class' => 'primary'),
+ )),
+);
+
+render();
diff --git a/module/system/ui/browsebackup.html.php b/module/system/ui/browsebackup.html.php
index ab7cf43811..1e3466d4a5 100644
--- a/module/system/ui/browsebackup.html.php
+++ b/module/system/ui/browsebackup.html.php
@@ -10,18 +10,24 @@ declare(strict_types=1);
*/
namespace zin;
-foreach($backups as $backup)
-{
- $backup->backupPerson = isset($backup->sqlSummary['account']) ? $backup->sqlSummary['account'] : '';
- if(empty($backup->sqlSummary['backupType'])) $backup->sqlSummary['backupType'] = '';
- $backup->type = $backup->sqlSummary['backupType'];
-}
$backups = initTableData($backups, $config->system->dtable->backup->fieldList, $this->system);
panel
(
set::size('lg'),
- set::title($lang->system->backup->systemInfo),
+ set::title($lang->backup->history),
+ to::headingActions
+ (
+ a
+ (
+ setClass('btn primary'),
+ icon('copy'),
+ set::href($this->createLink('system', 'backupPlatform')),
+ set::target('hiddenwin'),
+ $lang->backup->backup,
+ set('data-toggle', 'modal'),
+ ),
+ ),
div
(
setStyle('width', '66.6%'),
diff --git a/module/system/ui/restorebackup.html.php b/module/system/ui/restorebackup.html.php
new file mode 100644
index 0000000000..e46da2c04c
--- /dev/null
+++ b/module/system/ui/restorebackup.html.php
@@ -0,0 +1,23 @@
+
+ * @package mr
+ * @link https://www.zentao.net
+ */
+namespace zin;
+
+jsVar('restoreName', $restoreName);
+jsVar('error', $error);
+
+div
+(
+ setClass('restoreProgress text-3xl'),
+ $lang->system->backup->waittingStore,
+);
+
+render();
+