* devops setting

This commit is contained in:
zenggang
2023-07-31 08:02:25 +00:00
parent be9a3ba41f
commit b7a75d7b62
99 changed files with 11444 additions and 19 deletions
+60
View File
@@ -0,0 +1,60 @@
<?php
$config->instance = new stdclass;
$config->instance->keepDomainList = array();
$config->instance->keepDomainList['console'] = 'console';
$config->instance->keepDomainList['demo'] = 'demo';
$config->instance->keepDomainList['s3'] = 's3';
$config->instance->keepDomainList['s3-api'] = 's3-api';
$config->instance->seniorChartList = array();
$config->instance->seniorChartList['zentao'] = ['zentao-biz', 'zentao-max'];
$config->instance->seniorChartList['zentao-biz'] = ['zentao-max'];
$config->instance->adminer = new stdclass();
$config->instance->adminer->dbTypes = array();
$config->instance->adminer->dbTypes['mysql'] = 'mysql';
$config->instance->adminer->dbTypes['postgresql'] = 'pgsql';
$features = explode(',', getenv('QUICKON_FEATURES', ''));
$config->instance->enableAutoRestore = in_array('auto-rollback', $features);
global $lang, $app;
$app->loadLang('space');
$config->instance->actionList['start']['icon'] = 'play';
$config->instance->actionList['start']['className'] = 'ajax-submit';
$config->instance->actionList['start']['hint'] = $lang->instance->start;
$config->instance->actionList['start']['text'] = $lang->instance->start;
$config->instance->actionList['start']['url'] = array('module' => 'instance', 'method' => 'ajaxStart', 'params' => 'id={id}');
$config->instance->actionList['stop']['icon'] = 'off';
$config->instance->actionList['stop']['className'] = 'ajax-submit';
$config->instance->actionList['stop']['hint'] = $lang->instance->stop;
$config->instance->actionList['stop']['text'] = $lang->instance->stop;
$config->instance->actionList['stop']['data-confirm'] = $lang->instance->notices['confirmStop'];
$config->instance->actionList['stop']['url'] = array('module' => 'instance', 'method' => 'ajaxStop', 'params' => 'id={id}');
$config->instance->actionList['uninstall']['icon'] = 'trash';
$config->instance->actionList['uninstall']['hint'] = $lang->instance->uninstall;
$config->instance->actionList['uninstall']['text'] = $lang->instance->uninstall;
$config->instance->actionList['uninstall']['className'] = 'ajax-submit';
$config->instance->actionList['uninstall']['data-confirm'] = $lang->instance->notices['confirmUninstall'];
$config->instance->actionList['uninstall']['url'] = array('module' => 'instance', 'method' => 'ajaxUninstall', 'params' => 'id={id}');
$config->instance->actionList['visit']['icon'] = 'menu-my';
$config->instance->actionList['visit']['hint'] = $lang->instance->visit;
$config->instance->actionList['visit']['text'] = $lang->instance->visit;
$config->instance->actionList['visit']['target'] = '_blank';
$config->instance->actionList['visit']['url'] = array('module' => 'instance', 'method' => 'visit', 'params' => 'id={id}');
$config->instance->actionList['upgrade']['icon'] = 'refresh';
$config->instance->actionList['upgrade']['data-toggle'] = 'modal';
$config->instance->actionList['upgrade']['data-size'] = 'sm';
$config->instance->actionList['upgrade']['text'] = $lang->instance->upgrade;
$config->instance->actionList['upgrade']['hint'] = $lang->instance->upgrade;
$config->instance->actionList['upgrade']['url'] = helper::createLink('instance', 'upgrade', "id={id}");
$config->instance->actions = new stdclass();
$config->instance->actions->view = array();
$config->instance->actions->view['mainActions'] = array('visit', 'start', 'stop', 'upgrade');
$config->instance->actions->view['suffixActions'] = array('uninstall');
+865
View File
@@ -0,0 +1,865 @@
<?php
/**
* The control file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QuCheng Software Co,LTD, www.qucheng.com)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.com
*/
class instance extends control
{
/**
* Construct function.
*
* @param string $moduleName
* @param string $methodName
* @access public
* @return void
*/
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
$this->loadModel('action');
$this->loadModel('cne');
$this->loadModel('store');
}
/**
* Show instance view.
*
* @param int $id
* @param int $recTotal
* @param int $recPerPage
* @param int $page
* @access public
* @return void
*/
public function view($id, $recTotal = 0, $recPerPage = 20, $pageID = 1, $tab ='baseinfo' )
{
$this->loadModel('system');
$this->app->loadLang('system');
$instance = $this->instance->getByID($id);
if(empty($instance)) return print(js::alert($this->lang->instance->instanceNotExists) . js::locate($this->createLink('space', 'browse')));
$instance->latestVersion = $this->store->appLatestVersion($instance->appID, $instance->version);
$instance = $this->instance->freshStatus($instance);
$instanceMetric = $this->cne->instancesMetrics(array($instance));
$instanceMetric = $instanceMetric[$instance->id];
$this->lang->switcherMenu = $this->instance->getSwitcher($instance);
$this->app->loadClass('pager', true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$backupList = array();
$latestBackup = new stdclass;
if($tab == 'backup') $backupList = $this->instance->backupList($instance);
if(count($backupList)) $latestBackup = reset($backupList);
$hasRestoreLog = false;
foreach($backupList as $backup)
{
$backup->latest_restore_time = 0;
$backup->latest_restore_status = '';
foreach($backup->restores as $restore)
{
$hasRestoreLog = true;
if($restore->create_time > $backup->latest_restore_time)
{
$backup->latest_restore_time = $restore->create_time;
$backup->latest_restore_status = $restore->status;
}
}
}
$dbList = new stdclass;
$currentResource = new stdclass;
$customItems = array();
$dbList = $this->cne->appDBList($instance);
$currentResource = $this->cne->getAppConfig($instance);
$customItems = $this->cne->getCustomItems($instance);
$this->view->title = $instance->appName;
$this->view->instance = $instance;
$this->view->cloudApp = $this->loadModel('store')->getAppInfoByChart($instance->chart, $instance->channel, false);
$this->view->seniorAppList = $tab == 'baseinfo' ? $this->instance->seniorAppList($instance, $instance->channel) : array();
$this->view->actions = $this->loadModel('action')->getList('instance', $id);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->defaultAccount = $this->cne->getDefaultAccount($instance);
$this->view->instanceMetric = $instanceMetric;
$this->view->currentResource = $currentResource;
$this->view->customItems = $customItems;
$this->view->backupList = $backupList;
$this->view->hasRestoreLog = $hasRestoreLog;
$this->view->latestBackup = $latestBackup;
$this->view->dbList = $dbList;
$this->view->domain = $this->cne->getDomain($instance);
$this->view->tab = $tab;
$this->view->pager = $pager;
$this->display();
}
/**
* Display or save auto backup settings.
*
* @param int $instanceID
* @access public
* @return void
*/
public function backupSettings($instanceID)
{
$instance = $this->instance->getByID($instanceID);
if($_POST)
{
$this->instance->saveAutoBackupSettings($instance);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$backupSettings = $this->instance->getAutoBackupSettings($instanceID);
$startTime = strtotime($backupSettings->backupTime);
if($startTime < time()) $startTime = strtotime("+1 day $backupSettings->backupTime");
if($backupSettings->autoBackup)
{
$startBackupMessage = sprintf($this->lang->instance->backup->firstStartTime, $instance->name, date('Y-m-d H:i:s', $startTime));
return $this->send(array('result' => 'success', 'message' => $startBackupMessage));
}
return $this->send(array('result' => 'success', 'message' => $this->lang->instance->backup->disableAutoBackup));
}
$backupSettings = $this->instance->getAutoBackupSettings($instanceID);
$this->view->title = $this->lang->instance->backup->autoBackup;
$this->view->instance = $instance;
$this->view->backupSettings = $backupSettings;
$this->display();
}
/**
* Display or save auto restore settings.
*
* @param int $instanceID
* @access public
* @return void
*/
public function restoreSettings($instanceID)
{
$instance = $this->instance->getByID($instanceID);
if($_POST)
{
$this->instance->saveAutoRestoreSettings($instance);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$restoreSettings = $this->instance->getAutoRestoreSettings($instanceID);
$startTime = strtotime($restoreSettings->restoreTime);
if($startTime < time()) $startTime = strtotime("+1 day $restoreSettings->restoreTime");
if($restoreSettings->autoRestore)
{
$startRestoreMessage = sprintf($this->lang->instance->restore->firstStartTime, $instance->name, date('Y-m-d H:i:s', $startTime));
return $this->send(array('result' => 'success', 'message' => $startRestoreMessage));
}
return $this->send(array('result' => 'success', 'message' => $this->lang->instance->restore->disableAutoRestore));
}
$this->view->title = $this->lang->instance->restore->autoRestore;
$this->view->instance = $instance;
$this->view->restoreSettings = $this->instance->getAutoRestoreSettings($instanceID);
$this->display();
}
/**
* Cron task of auto backup.
*
* @param string $key
* @access public
* @return void
*/
public function autoBackup($key)
{
if($this->config->instance->enableAutoRestore) return; // Only one of auto backup and auto restore can be enabled.
$this->app->saveLog('Run auto backup at: ' . date('Y-md-d H:i:s'));
if($key != helper::readKey()) return;
$this->instance->autoBackup();
}
/**
* Cron task of auto restore.
*
* @param string $key
* @access public
* @return void
*/
public function autoRestore($key)
{
if(!$this->config->instance->enableAutoRestore) return; // Only one of auto backup and auto restore can be enabled.
$this->app->saveLog('Run auto restore at: ' . date('Y-md-d H:i:s'));
if($key != helper::readKey()) return;
$this->instance->autoRestore();
}
/**
* Edit instance app name.
*
* @param int $id
* @access public
* @return void
*/
public function setting($id)
{
$currentResource = new stdclass;
$instance = $this->instance->getByID($id);
$currentResource = $this->cne->getAppConfig($instance);
if(!empty($_POST))
{
$newInstance = fixer::input('post')->trim('name')->get();
$memoryKb = $newInstance->memory_kb;
unset($newInstance->memory_kb);
if(intval($currentResource->max->memory / 1024) != $memoryKb)
{
/* Check free memory size is enough or not. */
$clusterResource = $this->cne->cneMetrics();
$freeMemory = intval($clusterResource->metrics->memory->allocatable * 0.9); // Remain 10% memory for system.
if($memoryKb * 1024 > $freeMemory) $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->notEnoughResource));
/* Request CNE to adjust memory size. */
if(!$this->instance->updateMemorySize($instance, $memoryKb * 1024))
{
$this->send(array('result' => 'fail', 'message' => dao::getError()));
}
}
$this->instance->updateByID($id, $newInstance);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
if($newInstance->name != $instance->name)
{
$this->action->create('instance', $instance->id, 'editname', '', json_encode(array('result' => array('result' => 'success'), 'data' => array('oldName' => $instance->name, 'newName' => $newInstance->name))));
}
return $this->send(array('result' => 'success', 'load' => true, 'closeModal' => true));
}
$this->view->currentResource = $currentResource;
$this->view->instance = $instance;
$this->display();
}
/**
* Upgrade to senior serial.
*
* @param int $instanceID
* @param int $seniorAppID
* @param string $confirm
* @access public
* @return void
*/
public function toSenior($instanceID, $seniorAppID, $confirm = 'no')
{
$instance = $this->instance->getByID($instanceID);
$cloudApp = $this->store->getAppInfo($seniorAppID, $instance->channel, false);
if(empty($cloudApp)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->noAppInfo));
if($confirm == 'yes')
{
$success = $this->instance->upgradeToSenior($instance, $cloudApp);
if($success) $this->send(array('result' => 'success', 'message' => '', 'locate' => $this->inLink('view', "id=$instance->id")));
$this->send(array('result' => 'fail', 'message' => dao::getError()));
}
$this->view->title = $this->lang->instance->upgradeToSenior;
$this->view->instance = $instance;
$this->view->cloudApp = $cloudApp;
$this->display();
}
/**
* Upgrade instnace
*
* @param int $id
* @access public
* @return mixed
*/
public function upgrade($id)
{
$instance = $this->instance->getByID($id);
$instance->latestVersion = $this->store->appLatestVersion($instance->appID, $instance->version);
if($_POST)
{
if(empty($instance->latestVersion)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->noHigherVersion, 'closeModal' => true));
$postData = fixer::input('post')->get();
if($postData->confirm == 'yes') $success = $this->instance->upgrade($instance, $instance->latestVersion->version, $instance->latestVersion->app_version);
$logExtra = array('result' => 'success', 'data' => array('oldVersion' => $instance->appVersion, 'newVersion' => $instance->latestVersion->app_version));
if(!$success)
{
$logExtra['result'] = 'fail';
$this->action->create('instance', $instance->id, 'upgrade', '', json_encode($logExtra));
return $this->send(array('result' => 'fail', 'message' => !empty($logExtra['message']) ? $logExtra['message'] : $this->lang->instance->notices['upgradeFail'], 'closeModal' => true));
}
$this->action->create('instance', $instance->id, 'upgrade', '', json_encode($logExtra));
return $this->send(array('result' => 'success', 'message' => $this->lang->instance->notices['upgradeSuccess'], 'load' => $this->createLink('instance', 'view', "id=$id"), 'closeModal' => true));
}
$this->view->title = $this->lang->instance->upgrade . $instance->name;
$this->view->instance = $instance;
$this->display();
}
/**
* 访问一个应用。
* Visit a app.
*
* @param int $id
* @param int $externalID
* @access public
* @return void
*/
public function visit(int $id, int $externalID = 0): void
{
if(!$externalID)
{
$instance = $this->instance->getByID($id);
$url = $this->instance->url($instance);
}
else
{
$pipeline = $this->loadModel('pipeline')->getByID($externalID);
$url = $pipeline->url;
}
$this->locate($url);
}
/**
* (Not used at present.) Install app by custom settings.
*
* @param int $id
* @access public
* @return void
*/
public function customInstall($id)
{
// Disable custom installation in version 1.0.
$storeUrl = $this->createLink('store', 'appview', "id=$id");
return js::execute("window.parent.location.href='{$storeUrl}';");
}
/**
* Install app.
*
* @param int $appID
* @access public
* @return void
*/
public function install($appID)
{
$cloudApp = $this->store->getAppInfo($appID);
if(empty($cloudApp)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->noAppInfo));
if(empty($this->config->demoAccounts))
{
$clusterResource = $this->cne->cneMetrics();
$freeMemory = intval($clusterResource->metrics->memory->allocatable * 0.9); // Remain 10% memory for system.
if($cloudApp->memory > $freeMemory)
{
$this->view->cloudApp = $cloudApp;
$this->view->gapMemory = helper::formatKB(intval(($cloudApp->memory - $freeMemory)));
$this->view->requiredMemory = helper::formatKB(intval($cloudApp->memory));
$this->view->freeMemory = helper::formatKB(intval($freeMemory));
return $this->display('instance','resourceerror');
}
}
$versionList = $this->store->appVersionList($cloudApp->id);
$mysqlList = $this->cne->sharedDBList('mysql');
$pgList = $this->cne->sharedDBList('postgresql');
if(!empty($_POST))
{
$customData = fixer::input('post')
->trim('customName')->setDefault('customName', '')
->trim('customDomain')->setDefault('customDomain', '')
->trim('version')->setDefault('version', '')
->trim('dbType')->setDefault('dbType', 'unsharedDB')
->trim('dbService')
->setDefault('app_version', '')
->get();
if($customData->version && isset($versionList[$customData->version])) $customData->app_version = $versionList[$customData->version]->app_version;
if(isset($this->config->instance->keepDomainList[$customData->customDomain]) || $this->instance->domainExists($customData->customDomain)) return $this->send(array('result' => 'fail', 'message' => $customData->customDomain . $this->lang->instance->errors->domainExists));
if(!validater::checkLength($customData->customDomain, 20, 2)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->domainLength));
if(!validater::checkREG($customData->customDomain, '/^[a-z\d]+$/')) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->wrongDomainCharacter));
/* If select the version, replace the latest version of App by selected version. */
if($customData->version)
{
$cloudApp->version = $customData->version;
$cloudApp->app_version = $customData->app_version;
}
$sharedDB = new stdclass;
if(isset($cloudApp->dependencies->mysql) && $customData->dbType == 'sharedDB')
{
$sharedDB = zget($mysqlList, $customData->dbService);
}
elseif(isset($cloudApp->dependencies->postgresql) && $customData->dbType == 'sharedDB')
{
$sharedDB = zget($pgList, $customData->dbService);
}
$instance = $this->instance->install($cloudApp, $sharedDB, $customData);
if(!$instance) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->notices['installFail']));
unset($_GET['onlybody']);
$this->send(array('result' => 'success', 'message' => $this->lang->instance->notices['installSuccess'], 'load' => $this->createLink('instance', 'view', "id=$instance->id"), 'closeModal' => true));
}
$this->lang->switcherMenu = $this->instance->getInstallSwitcher($cloudApp);
$this->view->position[] = $this->view->title;
$this->view->title = $this->lang->instance->install . $cloudApp->alias;
$this->view->cloudApp = $cloudApp;
$this->view->versionList = array();
foreach($versionList as $version) $this->view->versionList[$version->version] = $version->app_version . " ({$version->version})";
$this->view->thirdDomain = $this->instance->randThirdDomain();
$this->view->mysqlList = $this->instance->dbListToOptions($mysqlList);
$this->view->pgList = $this->instance->dbListToOptions($pgList);
$this->display();
}
/**
* Uninstall app instance.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxUninstall($instanceID, $type = '')
{
if($type == 'external')
{
$instance = $this->loadModel('pipeline')->getByID($instanceID);
if(!$instance) return $this->send(array('result' => 'success', 'message' => $this->lang->instance->notices['success']));
return $this->send($this->fetch($instance->type, 'delete', array('id' => $instance->id)));
}
$instance = $this->instance->getByID($instanceID);
if(!$instance) return $this->send(array('result' => 'success', 'message' => $this->lang->instance->notices['success']));
$success = $this->instance->uninstall($instance);
$this->action->create('instance', $instance->id, 'uninstall', '', json_encode(array('result' => $success, 'app' => array('alias' => $instance->appName, 'app_version' => $instance->version))));
if($success) return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'uninstallSuccess'), 'locate' => $this->createLink('space', 'browse')));
return $this->send(array('result' => 'fail', 'message' => zget($this->lang->instance->notices, 'uninstallFail')));
}
/**
* Start app instance.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxStart($instanceID)
{
$instance = $this->instance->getByID($instanceID);
if(!$instance) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->instanceNotExists));
$result = $this->instance->start($instance);
$this->action->create('instance', $instance->id, 'start', '', json_encode(array('result' => $result, 'app' => array('alias' => $instance->appName, 'app_version' => $instance->version))));
if($result->code == 200) return $this->send(array('result' => 'success', 'load' => true, 'message' => zget($this->lang->instance->notices, 'startSuccess')));
return $this->send(array('result' => 'fail', 'message' => !empty($result->message) ? $result->message : zget($this->lang->instance->notices, 'startFail')));
}
/**
* Stop app instance.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxStop($instanceID)
{
$instance = $this->instance->getByID($instanceID);
if(!$instance) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->instanceNotExists));
$result = $this->instance->stop($instance);
$this->action->create('instance', $instance->id, 'stop', '', json_encode(array('result' => $result, 'app' => array('alias' => $instance->appName, 'app_version' => $instance->version))));
if($result->code == 200) return $this->send(array('result' => 'success', 'load' => true, 'message' => zget($this->lang->instance->notices, 'stopSuccess')));
return $this->send(array('result' => 'fail', 'message' => !empty($result->message) ? $result->message : zget($this->lang->instance->notices, 'stopFail')));
}
/**
* Query status of app instance.
*
* @access public
* @return void
*/
public function ajaxStatus()
{
$postData = fixer::input('post')->setDefault('idList', array())->get();
$instances = $this->instance->getByIdList($postData->idList);
$statusList = $this->instance->batchFresh($instances);
return $this->send(array('result' => 'success', 'data' => $statusList));
}
/**
* Backup instnacd by ajax.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxBackup($instanceID)
{
$instance = $this->instance->getByID($instanceID);
$success = $this->instance->backup($instance, $this->app->user);
if(!$success)
{
$this->action->create('instance', $instance->id, 'backup', '', json_encode(array('result' => array('result' => 'fail'))));
return $this->send(array('result' => 'fail', 'message' => zget($this->lang->instance->notices, 'backupFail')));
}
$this->action->create('instance', $instance->id, 'backup', '', json_encode(array('result' => array('result' => 'success'))));
return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'backupSuccess')));
}
/**
* Restore instance by ajax
*
* @access public
* @return void
*/
public function ajaxRestore()
{
$postData = fixer::input('post')
->trim('instanceID')
->trim('backupName')->get();
if(empty($postData->instanceID) || empty($postData->backupName)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->wrongRequestData));
$instance = $this->instance->getByID($postData->instanceID);
if(empty($instance))return print(js::alert($this->lang->instance->instanceNotExists) . js::locate($this->createLink('space', 'browse')));
$success = $this->instance->restore($instance, $this->app->user, $postData->backupName);
if(!$success)
{
$this->action->create('instance', $instance->id, 'restore', '', json_encode(array('result' => array('result' => 'fail'))));
return $this->send(array('result' => 'fail', 'message' => zget($this->lang->instance->notices, 'restoreFail')));
}
$this->action->create('instance', $instance->id, 'restore', '', json_encode(array('result' => array('result' => 'success'))));
return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'restoreSuccess')));
}
/**
* Delete backup by ajax.
*
* @param int $backupID
* @access public
* @return void
*/
public function ajaxDeleteBackup($backupID)
{
$success = $this->instance->deleteBackup($backupID, $this->app->user);
if(!$success) return $this->send(array('result' => 'fail', 'message' => zget($this->lang->instance->notices, 'deleteFail')));
return $this->send(array('result' => 'success', 'message' => zget($this->lang->instance->notices, 'deleteSuccess')));
}
/**
* Generate database auth parameters and jump to login page.
*
* @access public
* @return void
*/
public function ajaxDBAuthUrl()
{
$post = fixer::input('post')
->setDefault('namespace', 'default')
->setDefault('instanceID', 0)
->setDefault('dbType', '')
->get();
if(empty($post->dbName)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->dbNameIsEmpty));
$instance = $this->instance->getByID($post->instanceID);
if(empty($instance)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->instanceNotExists));
$detail = $this->loadModel('cne')->appDBDetail($instance, $post->dbName);
if(empty($detail)) return $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->notFoundDB));
$dbAuth = array();
$dbAuth['driver'] = zget($this->config->instance->adminer->dbTypes, $post->dbType, '');
$dbAuth['server'] = $detail->host . ':' . $detail->port;
$dbAuth['username'] = $detail->username;
$dbAuth['db'] = $detail->database;
$dbAuth['password'] = $detail->password;
$url = '/adminer?' . http_build_query($dbAuth);
$this->send(array('result' => 'success', 'message' => '', 'data' => array('url' => $url)));
}
/**
* Adjust instance memory size by ajax.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxAdjustMemory($instanceID)
{
$postData = fixer::input('post')->get();
/* Check free memory size is enough or not. */
$clusterResource = $this->cne->cneMetrics();
$freeMemory = intval($clusterResource->metrics->memory->allocatable * 0.9); // Remain 10% memory for system.
if($postData->memory_kb * 1024 > $freeMemory) $this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->notEnoughResource));
/* Request CNE to adjust memory size. */
$instance = $this->instance->getByID($instanceID);
if(!$this->instance->updateMemorySize($instance, $postData->memory_kb * 1024))
{
$this->send(array('result' => 'fail', 'message' => dao::getError()));
}
$this->send(array('result' => 'success', 'message' => ''));
}
/**
* Switch LDAP between enable and disable by ajax.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxSwitchLDAP($instanceID)
{
$instance = $this->instance->getByID($instanceID);
$postData = fixer::input('post')->get();
if($this->instance->switchLDAP($instance, $postData->enableLDAP == 'true'))
{
$this->send(array('result' => 'success', 'message' => ''));
}
$this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->switchLDAPFailed));
}
/**
* Switch SMTP between enable and disable by ajax.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxSwitchSMTP($instanceID)
{
$instance = $this->instance->getByID($instanceID);
$postData = fixer::input('post')->get();
if($this->instance->switchSMTP($instance, $postData->enableSMTP == 'true'))
{
$this->send(array('result' => 'success', 'message' => ''));
}
$this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->switchSMTPFailed));
}
/**
* Update custom settings by ajax. For example: env variables.
*
* @param int $instanceID
* @access public
* @return void
*/
public function ajaxUpdateCustom($instanceID)
{
$instance = $this->instance->getByID($instanceID);
if(!$instance) $this->send(array('result' => 'fail', 'message' => $this->lang->instance->instanceNotExists));
$postData = fixer::input('post')->get();
$settings = new stdclass;
$settings->force_restart = true;
$settings->settings_map = new stdclass;
$settings->settings_map->custom = $postData;
if($this->cne->updateConfig($instance, $settings))
{
$this->action->create('instance', $instanceID, 'updatecustom', '', json_encode($settings));
$this->send(array('result' => 'success', 'message' => ''));
}
$this->send(array('result' => 'fail', 'message' => $this->lang->instance->errors->setEnvFailed));
}
/**
* Delete expired demo instance by cron.
*
* @access public
* @return void
*/
public function deleteExpiredDemoInstance()
{
if(empty($this->config->demoAccounts)) return $this->send(array('result' => 'fail', 'message' => 'This api is only for demo enviroment.'));
$this->instance->deleteExpiredDemoInstance();
$this->send(array('result' => 'success', 'message' => ''));
}
/**
* Get instance info for q tool in console.
*
* @param int $id
* @access public
* @return mixed
*/
public function apiDetail($id)
{
if(!$this->checkCneToken())
{
helper::setStatus(401);
return print(json_encode(array('code' => 401, 'message' => 'Invalid token.')));
}
if(empty($id)) return print(json_encode(array('code' => 401, 'message' => 'Invalid id.')));
$instance = $this->instance->getByID($id);
if(empty($instance)) return print(json_encode(array('code' => 404, 'message' => 'Not found.', 'data' => array())));
$instance->space = $instance->spaceData && isset($instance->spaceData->k8space) ? $instance->spaceData->k8space : '';
unset($instance->desc);
unset($instance->spaceData);
return print(json_encode(array('code' => 200, 'message' => 'success', 'data' => $instance)));
}
/**
* Get instances list by account through api for q tool.
*
* @access public
* @return void
*/
public function apiBrowse()
{
if(!$this->checkCneToken())
{
helper::setStatus(401);
return print(json_encode(array('code' => 401, 'message' => 'Invalid token.')));
}
$requestBody = json_decode(file_get_contents("php://input"));
$account = zget($requestBody, 'account', '');
if(empty($account)) return print(json_encode(array('code' => 700, 'message' => 'Account is required.', 'data' => new stdclass)));
$recPerPage = zget($requestBody, 'perPage', 20);
$pageID = zget($requestBody, 'page', 1);
$this->app->loadClass('pager', true);
$pager = pager::init(0, $recPerPage, $pageID);
$instanceList = $this->instance->getByAccount($account, $pager);
$result = new stdclass;
$result->list = $instanceList;
$result->page = $pageID;
$result->perPage = $recPerPage;
$result->pageTotal = $pager->pageTotal;
$result->total = $pager->recTotal;
return print(json_encode(array('code' => 200, 'message' => 'success', 'data' => $result)));
}
/**
* Install app by api for q tool.
*
* @access public
* @return void
*/
public function apiInstall()
{
if(!$this->checkCneToken())
{
helper::setStatus(401);
return print(json_encode(array('code' => 401, 'message' => 'Invalid token.')));
}
$requestBody = json_decode(file_get_contents("php://input"));
$chart = zget($requestBody , 'chart', '');
if(empty($chart)) return print(json_encode(array('code' => 701, 'message' => 'Param chart is required.')));
$user = null;
$account = zget($requestBody, 'account', '');
if($account) $user = $this->loadModel('user')->getById($account);
if(empty($user)) $user = $this->loadModel('company')->getAdmin();
if(empty($user)) return print(json_encode(array('code' => 703, 'message' => 'No user.')));
$this->app->user = $user;
$name = zget($requestBody , 'name', '');
$channel = zget($requestBody , 'channel', 'stable');
$k8name = zget($requestBody , 'k8name', '');
if($k8name && $this->instance->k8nameExists($k8name)) return print(json_encode(array('code' => 706, 'message' => $k8name . ' has been used, please change it and try again.')));
$thirdDomain = zget($requestBody , 'domain', '');
if($this->instance->domainExists($thirdDomain)) return print(json_encode(array('code' => 705, 'message' => $thirdDomain . ' has been used, please change it and try again.')));
$cloudApp = $this->store->getAppInfoByChart($chart, $channel, false);
if(empty($cloudApp)) return print(json_encode(array('code' => 702, 'message' => 'App not found.')));
$result = $this->instance->apiInstall($cloudApp, $thirdDomain, $name, $k8name, $channel);
if($result) return print(json_encode(array('code' => 200, 'message' => 'success', 'data' => new stdclass)));
return print(json_encode(array('code' => 704, 'message' => 'Fail to install app.', 'data' => new stdclass)));
}
/**
* Check CNE token.
*
* @access private
* @return bool
*/
private function checkCneToken()
{
$token = zget($_SERVER, 'HTTP_TOKEN');
return $token == $this->config->CNE->api->token;
}
}
+1
View File
@@ -0,0 +1 @@
#backupSettingForm{ margin-bottom: 40px;}
+5
View File
@@ -0,0 +1,5 @@
#installForm .advanced {padding: 10px 0; border-bottom: solid 1px #e4e4e4;}
#installForm .advanced a {font-weight: 700;}
#installForm .advanced .icon {display: inline-block; margin-left: 10px;}
#installForm .advanced a:hover, #installForm table td a:focus, #installForm table td a:hover {color: #61be68;}
#installForm td {height: 46px;}
+1
View File
@@ -0,0 +1 @@
.modal-message {font-weight: bold; padding: 20px;}
+32
View File
@@ -0,0 +1,32 @@
#mainContent .nav-tabs li>a::before {height: 0;}
.instance-name h3 {display: inline-block; padding-left: 10px;}
.instance-name > span {font-size: 14px; font-weight: bolder; padding: 3px 3px; margin: 0 5px;}
.instance-panel .btn-group .btn {width: 60px;}
.instance-panel .btn-group i {font-size: 24px;}
.instance-status span {display: inline-block; margin-right: 10px; padding-bottom: 1px;}
.instance-status i {font-size: 18px;}
.instance-source span {display: inline-block; margin-right: 10px; width: 100px;}
#senior-app-desc a {color: #61be68}
a#serialDiff {color: #ff9800;}
#seniorAppPanel span.text-info:hover {color: #2196f3;}
.instance-log .panel-body {padding-bottom: 8px; padding-left: 10px;}
.instance-log .panel-body table {margin-bottom: 0;}
.usage-box {border-radius: 3px;}
.c-title {text-align: center; padding-top: 10px; font-size: 15px}
.progress-pie {margin: 10px auto;}
.instance-panel > div > a:last-child { margin-left: 8px;}
.solution-link {display: inline-block; margin-left: 20px;}
#backup .panel {padding: 10px;}
#backup .panel .btn-toolbar{padding: 0 0 10px 0;}
#backup .panel .panel-heading {height: 50px;}
#backup table.table {margin-bottom: 20px; width: auto;}
#backup table th.actions {padding-left: 15px;}
#backup table td>.btn {padding-left: 5px; padding-right: 5px;}
#backup .btn.btn-info[disabled] {color: rgba(255,255,255,.7); background-color: #61be68;}
#advance .panel-title span {padding-left: 10px;}
#advance hr {margin: 5px 20px;}
#advance .scalable-input{height: 26px;}
#advance .center{text-align: center;}
#advance .hide{display: none}
+8
View File
@@ -0,0 +1,8 @@
.detail-header .icon-info-sign {color: rgba(var(--color-secondary-500-rgb),var(--tw-bg-opacity));}
#dynamicPager {justify-content: flex-end;}
#dynamicPager .ghost {color: rgb(131, 138, 157);}
#dynamicTable a {color: inherit;}
.progress-container {word-break: keep-all; white-space: nowrap;}
.progress-container i {margin: auto; margin-right: 6px;}
.progress-container .progress {margin: auto; width: 100%; height: .7rem; margin-left: 6px; margin-right: 15px;}
.label-dot {display: inline-block; width: 8px; height: 8px; padding: 0; line-height: 20px; text-indent: -9999em; border-radius: 50%;}
+64
View File
@@ -0,0 +1,64 @@
$(function()
{
$(".form-time").datetimepicker({
weekStart: 1,
todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
startView: 1,
minView: 0,
maxView: 1,
forceParse: 0,
format: 'hh:ii'
});
$("input[type=checkbox][name='autoBackup[]']").on('change', function(event)
{
var enabled = $("input[type=checkbox][name='autoBackup[]']:checked").length > 0;
if(enabled)
{
$('.backup-settings').show();
}
else
{
$('.backup-settings').hide();
}
});
$("input[type=checkbox][name='autoBackup[]']").change();
$("#keepDays").on('input', function(event)
{
console.log(event,event.target.value);
event.target.value = event.target.value.replace(/[^\d]+/g,'');
if(Number(event.target.value) < 1)
{
event.target.value = 1;
}
if(Number(event.target.value) > 30)
{
event.target.value = 30;
}
});
$('#backupSettingForm #saveSetting').on('click', function()
{
var settings = $('#backupSettingForm').serialize();
$.post(createLink('instance', 'backupSettings', 'id=' + instanceID), settings).done(function(response)
{
var res = JSON.parse(response);
if(res.result == 'success')
{
parent.window.$.closeModal();
parent.window.bootAlert({title: instanceNotices.success, message:res.message});
}
else
{
var errMsg = res.message instanceof Array ? res.message.join('<br/>') : res.message;
parent.window.bootAlert({title: instanceNotices.fail, message: errMsg});
}
});
});
});
+7
View File
@@ -0,0 +1,7 @@
$(function()
{
$('input[type=number]').on('change', function(event)
{
if($(event.target).val() <= 1) $(event.target).val(1);
});
});
+48
View File
@@ -0,0 +1,48 @@
$(function()
{
$('#installForm').on('submit', function(event)
{
event.preventDefault();
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.installing + '</div>',
});
$.post($('#installForm').attr('action'), $('#installForm').serializeArray()).done(function(response)
{
loadingDialog.modal('hide');
let res = JSON.parse(response);
if(res.result == 'success')
{
config.onlybody = 'no';
window.parent.$.apps.open(res.locate, 'space');
}
else
{
alert(res.message);
}
});
});
$("input[type=radio][name='dbType']").on('change', function(event)
{
if(event.target.value == 'sharedDB')
{
$("select[name=dbService]").closest('td').show();
}
else
{
$("select[name=dbService]").closest('td').hide();
}
});
$(".advanced a").on('click', function(event)
{
let downArrow = $(".advanced a .icon-chevron-double-down");
let upArrow = $(".advanced a .icon-chevron-double-up");
if(downArrow.length >0 ) downArrow.removeClass('icon-chevron-double-down').addClass('icon-chevron-double-up');
if(upArrow.length >0 ) upArrow.removeClass('icon-chevron-double-up').addClass('icon-chevron-double-down');
});
});
+49
View File
@@ -0,0 +1,49 @@
$(function()
{
$(".form-time").datetimepicker({
weekStart: 1,
todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
startView: 1,
minView: 0,
maxView: 1,
forceParse: 0,
format: 'hh:ii'
});
$("input[type=checkbox][name='autoRestore[]']").on('change', function(event)
{
var enabled = $("input[type=checkbox][name='autoRestore[]']:checked").length > 0;
if(enabled)
{
$('.restore-settings').show();
}
else
{
$('.restore-settings').hide();
}
});
$("input[type=checkbox][name='autoRestore[]']").change();
$('#restoreSettingForm #saveSetting').on('click', function()
{
var settings = $('#restoreSettingForm').serialize();
$.post(createLink('instance', 'restoreSettings', 'id=' + instanceID), settings).done(function(response)
{
var res = JSON.parse(response);
if(res.result == 'success')
{
parent.window.$.closeModal();
parent.window.bootAlert({title: instanceNotices.success, message:res.message});
}
else
{
var errMsg = res.message instanceof Array ? res.message.join('<br/>') : res.message;
parent.window.bootAlert({title: instanceNotices.fail, message: errMsg});
}
});
});
});
+14
View File
@@ -0,0 +1,14 @@
$(function(){
$("#toSeniorForm input#readtrue").on('change', function()
{
if($('#toSeniorForm input#readtrue:checked').length > 0)
{
$('#toSeniorForm button[type=submit]').attr('disabled', false);
}
else
{
$('#toSeniorForm button[type=submit]').attr('disabled', true);
}
});
$("#toSeniorForm input#readtrue").change();
});
+30
View File
@@ -0,0 +1,30 @@
$(function()
{
$('#upgradeForm').on('submit', function(event)
{
event.preventDefault();
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.upgrading + '</div>',
});
$.post($('#upgradeForm').attr('action'), $('#upgradeForm').serializeArray()).done(function(response)
{
loadingDialog.modal('hide');
window.parent.$('#triggerModal').modal('hide');
let res = JSON.parse(response);
if(res.result == 'success')
{
config.onlybody = 'no';
window.parent.$.apps.reload('space', createLink('space', 'browse'), 'space');
window.parent.location.reload();
}
else
{
alert(res.message);
}
});
});
});
+502
View File
@@ -0,0 +1,502 @@
$(function()
{
$('#memBtn').on('click', function(event)
{
bootbox.confirm(instanceNotices.adjustMemory, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.adjusting + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxAdjustMemory', 'id=' + id, 'json');
var adjustData = {memory_kb: $('select[name=memory_kb]').val()};
$.post(url, adjustData).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.$.apps.open(createLink('instance', 'view', 'id=' + id), 'space');
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('#ldapBtn').on('click', function(event)
{
bootbox.confirm(instanceNotices.switchLDAP, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.switching + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxSwitchLDAP', 'id=' + id, 'json');
var postData = {enableLDAP: $("[name='enableLDAP[]']:checked").length > 0};
$.post(url, postData).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.location.reload();
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('#smtpBtn').on('click', function(event)
{
bootbox.confirm(instanceNotices.switchSMTP, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.switching + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxSwitchSMTP', 'id=' + id, 'json');
var postData = {enableSMTP: $("[name='enableSMTP[]']:checked").length > 0};
$.post(url, postData).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.location.reload();
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('#customBtn').on('click', function(event)
{
var errors = '';
$("#customForm").find("input[type=text]").each(function(index, item)
{
if($(item).val().trim().length == 0)
{
errors += $(item).attr('placeholder') + instanceNotices.required + '<br/>';
}
});
if(errors.length > 0)
{
bootbox.alert(
{
title: instanceNotices.error,
message: errors,
});
return;
}
bootbox.confirm(instanceNotices.confirmCustom, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.setting + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxUpdateCustom', 'id=' + id, 'json');
var formData = $('#customForm').serializeArray();
var customData = {};
formData.forEach(function(item, index){
customData[item.name] = item.value;
});
$.post(url, customData).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.location.reload();
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('.btn-uninstall').on('click', function(event)
{
bootbox.confirm(instanceNotices.confirmUninstall, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.uninstalling + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxUninstall', 'id=' + id, 'json');
$.post(url).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.$.apps.open(createLink('space', 'browse'), 'space');
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('.btn-start').on('click', function(event)
{
bootbox.confirm(instanceNotices.confirmStart, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.starting + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxStart', 'id=' + id, 'json');
$.post(url).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.location.reload();
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('.btn-stop').on('click', function(event)
{
bootbox.confirm(instanceNotices.confirmStop, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.stopping + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxStop', 'id=' + id, 'json');
$.post(url).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
window.location.reload();
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('.btn-backup').on('click', function(event)
{
$('#confirmRestore').modal('hide');
bootbox.confirm(instanceNotices.confirmBackup, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.backuping + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'ajaxBackup', 'id=' + id, 'json');
$.post(url).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
bootbox.alert(
{
title: instanceNotices.success,
message: res.message,
callback: function(){window.location.reload();}
});
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('.btn-restore').click(function()
{
let backupName = $(this).attr('backup-name');
let instanceID = $(this).attr('instance-id');
$('#confirmRestore #submitRestore').data('backup-name', backupName);
$('#confirmRestore #submitRestore').data('instance-id', instanceID);
$('#confirmRestore').modal('show');
});
$('#submitRestore').on('click', function(event)
{
$('#confirmRestore').modal('hide');
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.restoring + '</div>',
});
var instanceID = $(event.target).closest('button').data('instance-id');
var backupName = $(event.target).closest('button').data('backup-name');
var url = createLink('instance', 'ajaxRestore', '', 'json');
$.post(url, { instanceID, backupName }).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
bootbox.alert(
{
title: instanceNotices.success,
message: res.message,
callback: function(){window.location.reload();}
});
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
$('.btn-delete-backup').on('click', function(event)
{
bootbox.confirm(instanceNotices.confirmDelete, function(result)
{
if(!result) return;
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.deleting + '</div>',
});
var id = $(event.target).closest('button').attr('backup-id');
var url = createLink('instance', 'ajaxDeleteBackup', 'id=' + id, 'json');
$.post(url).done(function(response)
{
loadingDialog.modal('hide');
var res = JSON.parse(response);
if(res.result == 'success')
{
bootbox.alert(
{
title: instanceNotices.success,
message: res.message,
callback: function(){window.location.reload();}
});
}
else
{
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
});
});
$('button.db-login').on('click', function(event)
{
var dbName = $(event.target).data('db-name');
var dbType = $(event.target).data('db-type');
var instanceID = $(event.target).data('id');
$.post(createLink('instance', 'ajaxDBAuthUrl'), {dbName, dbType, instanceID}).done(function(res)
{
var response = JSON.parse(res);
if(response.result == 'success')
{
window.parent.open(response.data.url, 'Adminer');
}
else
{
bootbox.alert(response.message);
}
});
});
var enableTimer = true;
window.parent.$(window.parent.document).on('showapp', function(event, app)
{
enableTimer = app.code == 'space';
});
setInterval(function()
{
if(!enableTimer) return;
var statusURL = createLink('instance', 'ajaxStatus');
$.post(statusURL, {idList: instanceIdList}).done(function(response)
{
var res = JSON.parse(response);
if(res.result == 'success' && res.data instanceof Array)
{
res.data.forEach(function(instance)
{
if($(".instance-status[instance-id=" + instance.id + "]").data('status') != instance.status) window.location.reload();
});
}
if(res.locate) window.parent.location.href = res.locate;
});
}, 1000 * 5);
$('[data-toggle="tooltip"]').tooltip();
/* Count down for demo instance. */
setInterval(function()
{
var nowSeconds = Math.round((new Date).getTime() / 1000);
$('.count-down').each(function(index, item)
{
var createdAt = $(item).data('created-at');
var passSeconds = nowSeconds - createdAt;
var leftSeconds = (demoAppLife ? demoAppLife : 30) * 60 - passSeconds;
if(leftSeconds < 0)
{
window.parent.location.href = createLink('space', 'browse');
}
else
{
var minutes = Math.floor(leftSeconds / 60);
var seconds = Math.round(leftSeconds % 60);
$(item).find('.left-time').text(('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2));
}
})
}, 1000)
$('#replicas-edit').on('click', function()
{
$('#replicas-input').show()
$('#replicas-text').hide()
$('#replicas-save').show()
$('#replicas-edit').hide()
})
$('#replicas-save').on('click', function()
{
var loadingDialog = bootbox.dialog(
{
message: '<div class="text-center"><i class="icon icon-spinner-indicator icon-spin"></i>&nbsp;&nbsp;' + instanceNotices.adjusting + '</div>',
});
var id = $(event.target).closest('button').attr('instance-id');
var url = createLink('instance', 'replicas', 'id=' + id, 'json');
var adjustData = {replicas: $('#replicas-input').val()};
$.post(url, adjustData).done(function(response)
{
var res = JSON.parse(response);
if(res.result == 'success')
{
window.parent.location.reload();
}
else
{
loadingDialog.modal('hide');
bootbox.alert(
{
title: instanceNotices.fail,
message: res.message,
});
}
});
})
})
+43
View File
@@ -0,0 +1,43 @@
window.openAdminer = function()
{
var dbName = $(this).data('dbname');
var dbType = $(this).data('dbtype');
var instanceID = $(this).data('id');
$.ajaxSubmit
(
{
url: $.createLink('instance', 'ajaxDBAuthUrl'),
method: 'POST', data: {dbName, dbType, instanceID},
onSuccess: (response) =>
{
if(response.result == 'success')
{
window.open(response.data.url, 'Adminer');
}
else
{
zui.Modal.alert(response.message);
}
}
}
);
}
var reloadTimes = 0;
window.afterPageUpdate = function()
{
setTimeout(function()
{
if(reloadTimes > 20) return;
if($('#statusTD').data('reload') === true || $('#memoryRate').data('load') == true)
{
reloadTimes++;
fetchContent({url: $.createLink('instance', 'view', 'id=' + instanceID),
selector: '#instanceInfoContainer',
id: 'instanceInfoContainer',
target: '#instanceInfoContainer',
});
}
}, 4000);
}
+333
View File
@@ -0,0 +1,333 @@
<?php
$lang->instance = new stdclass;
$lang->instance->name = '名称';
$lang->instance->appName = '应用类型';
$lang->instance->version = '版本';
$lang->instance->status = '状态';
$lang->instance->cpu = 'CPU';
$lang->instance->mem = '内存';
$lang->instance->space = '空间';
$lang->instance->domain = '域名';
$lang->instance->visitIP = '访问方式';
$lang->instance->dbType = '数据库';
$lang->instance->advanceOption = '高级选项';
$lang->instance->baseInfo = '基本信息';
$lang->instance->backupAndRestore = '备份';
$lang->instance->advance = '高级';
$lang->instance->enableLDAP = '启用LDAP';
$lang->instance->linkLDAP = '集成LDAP';
$lang->instance->enableSMTP = '启用SMTP';
$lang->instance->customSetting = '自定义配置';
$lang->instance->upgradeToSenior = '升级到高级版';
$lang->instance->updateDomain = '更新域名';
$lang->instance->updateLog = '更新日志';
$lang->instance->start = '启动';
$lang->instance->restart = '重启';
$lang->instance->stop = '关闭';
$lang->instance->install = '安装';
$lang->instance->update = '更新';
$lang->instance->upgrade = '升级';
$lang->instance->customInstall = '自定义安装';
$lang->instance->uninstall = '删除';
$lang->instance->visit = '访问';
$lang->instance->editName = '修改名称';
$lang->instance->cpuCore = '核';
$lang->instance->scalable = '应用水平扩容';
$lang->instance->change = '修改';
$lang->instance->systemLDAPInactive = '未开启系统LDAP';
$lang->instance->toSystemLDAP = '去启用';
$lang->instance->enableSMTP = '启用SMTP';
$lang->instance->systemSMTPInactive = '未开启系统SMTP';
$lang->instance->toSystemSMTP = '去启用';
$lang->instance->serviceInfo = '服务信息';
$lang->instance->appTemplate = '应用模板';
$lang->instance->source = '来源';
$lang->instance->installBy = '创建者';
$lang->instance->installAt = '创建时间';
$lang->instance->runDuration = '已运行';
$lang->instance->defaultAccount = '默认用户';
$lang->instance->defaultPassword = '默认密码';
$lang->instance->operationLog = '操作记录';
$lang->instance->installedService = '已安装服务';
$lang->instance->runningService = '运行中的服务';
$lang->instance->installApp = '安装应用';
$lang->instance->cpuUsage = 'CPU占用';
$lang->instance->memUsage = '内存占用';
$lang->instance->memTotal = '(共%s)';
$lang->instance->currentMemory = '当前内存';
$lang->instance->adjustMem = '调整内存';
$lang->instance->setting = '设置';
$lang->instance->saveSetting = '保存设置';
$lang->instance->leftTime = '剩余';
$lang->instance->switchTo = '升级到';
$lang->instance->or = '或';
$lang->instance->hasRead = '已阅读';
$lang->instance->stopInstanceTips = '关闭服务后才能升级到高级版!';
$lang->instance->dbTypes = array();
$lang->instance->dbTypes['sharedDB'] = '共享数据库';
$lang->instance->dbTypes['unsharedDB'] = '独享数据库';
$lang->instance->backup = new stdclass;
$lang->instance->backup->common = '备份';
$lang->instance->backup->date = '备份时间';
$lang->instance->backup->operator = '备份人';
$lang->instance->backup->type = '备份类型';
$lang->instance->backup->backupStatus = '备份状态';
$lang->instance->backup->restoreStatus = '回滚状态';
$lang->instance->backup->restoreOperator = '回滚人';
$lang->instance->backup->restoreTime = '回滚时间';
$lang->instance->backup->action = '操作';
$lang->instance->backup->restore = '回滚';
$lang->instance->backup->restoreInfo = '回滚信息';
$lang->instance->backup->delete = '删除';
$lang->instance->backup->rebackup = '重试备份';
$lang->instance->backup->create = '创建备份';
$lang->instance->backup->database = '数据库';
$lang->instance->backup->dbType = '类型';
$lang->instance->backup->dbName = '名称';
$lang->instance->backup->dbStatus = '状态';
$lang->instance->backup->dbSpentSeconds = '耗时(秒)';
$lang->instance->backup->dbSize = '大小';
$lang->instance->backup->volumne = '数据卷';
$lang->instance->backup->volName = '名称';
$lang->instance->backup->volMountName = '挂载目录';
$lang->instance->backup->volStatus = '状态';
$lang->instance->backup->volSpentSeconds = '耗时(秒)';
$lang->instance->backup->volSize = '大小';
$lang->instance->backup->lastRestore = '上次回滚';
$lang->instance->backup->restoreDate = '回滚时间';
$lang->instance->backup->latestBackupAt = '上次备份时间';
$lang->instance->backup->backupBeforeRestore = '回滚前建议您先备份!';
$lang->instance->backup->enableAutoBackup = '开启自动备份';
$lang->instance->backup->autoBackup = '自动备份';
$lang->instance->backup->cycleDays = '备份周期';
$lang->instance->backup->backupTime = '备份时间';
$lang->instance->backup->keepDays = '保留天数';
$lang->instance->backup->keepDayRange = '请输入1~30之间的整数';
$lang->instance->backup->firstStartTime = '%s 首次备份将于%s 执行';
$lang->instance->backup->invalidTime = '无效的时间';
$lang->instance->backup->disableAutoBackup = '自动备份已关闭';
$lang->instance->backup->keepBackupBySystem = '备份数据超过1条时系统才会删除过期的自动备份数据。';
$lang->instance->backup->cycleList[1] = '每日';
$lang->instance->backup->operators = array();
$lang->instance->backup->operators['auto'] = '自动备份';
$lang->instance->backup->statusList = array();
$lang->instance->backup->statusList['success'] = '成功';
$lang->instance->backup->statusList['failed'] = '失败';
$lang->instance->backup->statusList['pending'] = '等待中';
$lang->instance->backup->statusList['processing'] = '备份中';
$lang->instance->backup->statusList['inprogress'] = '备份中';
$lang->instance->backup->statusList['completed'] = '完成';
$lang->instance->backup->statusList['executedFailed'] = '失败';
$lang->instance->backup->statusList['uploading'] = '上传中';
$lang->instance->backup->statusList['deleting'] = '删除中';
$lang->instance->backup->statusList['uploadFailed'] = '上传失败';
$lang->instance->backup->statusList['downloading'] = '下载中';
$lang->instance->backup->statusList['downloadFailed'] = '下载失败';
$lang->instance->restore = new stdclass;
$lang->instance->restore->autoRestore = '自动还原';
$lang->instance->restore->enableAutoRestore = '开启自动还原';
$lang->instance->restore->cycleDays = '还原周期';
$lang->instance->restore->restoreTime = '还原时间';
$lang->instance->restore->invalidTime = '无效的时间';
$lang->instance->restore->disableAutoRestore = '自动还原已关闭';
$lang->instance->restore->firstStartTime = '%s 首次自动还原将于%s 执行';
$lang->instance->restore->cycleList[1] = '每日';
$lang->instance->restore->statusList = array();
$lang->instance->restore->statusList['pending'] = '等待中';
$lang->instance->restore->statusList['inprogress'] = '进行中';
$lang->instance->restore->statusList['completed'] = '完成';
$lang->instance->restore->statusList['failed'] = '失败';
$lang->instance->dbList = '数据库';
$lang->instance->dbName = '名称';
$lang->instance->dbStatus = '状态';
$lang->instance->dbType = '类型';
$lang->instance->action = '操作';
$lang->instance->management = '管理';
$lang->instance->dbReady = '正常';
$lang->instance->dbWaiting = '等待就绪';
$lang->instance->log = new stdclass;
$lang->instance->log->date = '日期';
$lang->instance->log->message = '内容';
$lang->instance->actionList = array();
$lang->instance->actionList['install'] = '安装了%s';
$lang->instance->actionList['uninstall'] = '删除了%s';
$lang->instance->actionList['start'] = '启动了%s';
$lang->instance->actionList['stop'] = '关闭了%s';
$lang->instance->actionList['editname'] = '修改了名称';
$lang->instance->actionList['upgrade'] = '升级了%s';
$lang->instance->actionList['backup'] = '备份了%s';
$lang->instance->actionList['restore'] = '回滚了%s';
$lang->instance->actionList['adjustmemory'] = '调整 %s 的内存到 %s';
$lang->instance->actionList['adjustreplicas'] = '调整 %s 的副本数到 %s';
$lang->instance->actionList['enableldap'] = '启用了LDAP';
$lang->instance->actionList['disableldap'] = '禁用了LDAP';
$lang->instance->actionList['enablesmtp'] = '启用了SMTP';
$lang->instance->actionList['disablesmtp'] = '禁用了SMTP';
$lang->instance->actionList['updatecustom'] = '修改了自定义配置';
$lang->instance->actionList['tosenior'] = '升级服务到高级版';
$lang->instance->actionList['saveautobackupsettings'] = '修改了自动备份设置';
$lang->instance->actionList['saveautorestoresettings'] = '修改了自动还原设置';
$lang->instance->actionList['autobackup'] = '系统执行了自动备份';
$lang->instance->actionList['autorestore'] = '系统执行了自动还原';
$lang->instance->actionList['deleteexpiredbackup'] = '系统删除了过期的自动备份';
$lang->instance->sourceList = array();
$lang->instance->sourceList['cloud'] = '渠成公共市场';
$lang->instance->sourceList['local'] = '本地市场';
$lang->instance->channelList = array();
$lang->instance->channelList['test'] = '测试版';
$lang->instance->channelList['stable'] = '稳定版';
$lang->instance->statusList = array();
$lang->instance->statusList['installationFail'] = '安装失败';
$lang->instance->statusList['creating'] = '创建中';
$lang->instance->statusList['initializing'] = '初始化';
$lang->instance->statusList['pulling'] = '下载中';
$lang->instance->statusList['startup'] = '启动中';
$lang->instance->statusList['starting'] = '启动中';
$lang->instance->statusList['running'] = '运行中';
$lang->instance->statusList['suspending'] = '暂停中';
$lang->instance->statusList['suspended'] = '已暂停';
$lang->instance->statusList['installing'] = '安装中';
$lang->instance->statusList['uninstalling'] = '删除中';
$lang->instance->statusList['stopping'] = '关闭中';
$lang->instance->statusList['stopped'] = '已关闭';
$lang->instance->statusList['destroying'] = '销毁中';
$lang->instance->statusList['destroyed'] = '已销毁';
$lang->instance->statusList['abnormal'] = '异常';
$lang->instance->statusList['upgrading'] = '更新中';
$lang->instance->statusList['unknown'] = '未知';
$lang->instance->htmlStatusesClass = array();
$lang->instance->htmlStatusesClass['running'] = 'success';
$lang->instance->htmlStatusesClass['stopped'] = 'default';
$lang->instance->htmlStatusesClass['abnormal'] = 'danger';
$lang->instance->htmlStatusesClass['installationFail'] = 'danger';
$lang->instance->htmlStatusesClass['busy'] = "warning";
$lang->instance->memOptions = array();
$lang->instance->memOptions[128 * 1024] = '128MB';
$lang->instance->memOptions[256 * 1024] = '256MB';
$lang->instance->memOptions[512 * 1024] = '512MB';
$lang->instance->memOptions[1024 * 1024] = '1GB';
$lang->instance->memOptions[2048 * 1024] = '2GB';
$lang->instance->memOptions[4096 * 1024] = '4GB';
$lang->instance->memOptions[8192 * 1024] = '8GB';
$lang->instance->memOptions[16384 * 1024] = '16GB';
$lang->instance->memOptions[32768 * 1024] = '32GB';
$lang->instance->componentFields = array();
$lang->instance->componentFields['replicas'] = '副本数';
$lang->instance->componentFields['cpu_limit'] = 'CPU';
$lang->instance->componentFields['mem_limit'] = '内存';
$lang->instance->notices = array();
$lang->instance->notices['success'] = '成功';
$lang->instance->notices['fail'] = '失败';
$lang->instance->notices['error'] = '错误';
$lang->instance->notices['confirmStart'] = '确定启动该应用吗?';
$lang->instance->notices['confirmStop'] = '确定关闭该应用吗?';
$lang->instance->notices['confirmUninstall'] = '确定删除该应用吗?';
$lang->instance->notices['startSuccess'] = '启动成功';
$lang->instance->notices['startFail'] = '启动失败';
$lang->instance->notices['stopSuccess'] = '关闭成功';
$lang->instance->notices['stopFail'] = '关闭失败';
$lang->instance->notices['uninstallSuccess'] = '删除成功';
$lang->instance->notices['uninstallFail'] = '删除失败';
$lang->instance->notices['installSuccess'] = '安装成功';
$lang->instance->notices['installFail'] = '安装失败';
$lang->instance->notices['upgradeSuccess'] = '升级成功';
$lang->instance->notices['upgradeFail'] = '升级失败';
$lang->instance->notices['backupSuccess'] = '备份任务已提交';
$lang->instance->notices['backupFail'] = '备份失败';
$lang->instance->notices['restoreSuccess'] = '回滚任务已提交';
$lang->instance->notices['restoreFail'] = '回滚失败';
$lang->instance->notices['deleteSuccess'] = '删除成功';
$lang->instance->notices['deleteFail'] = '删除失败';
$lang->instance->notices['starting'] = '启动中,请稍候...';
$lang->instance->notices['stopping'] = '关闭中,请稍候...';
$lang->instance->notices['installing'] = '安装中,请稍候...';
$lang->instance->notices['uninstalling'] = '删除中,请稍候...';
$lang->instance->notices['upgrading'] = '升级中,请稍候...';
$lang->instance->notices['backuping'] = '备份中,请稍候...';
$lang->instance->notices['restoring'] = '回滚中,请稍候...';
$lang->instance->notices['deleting'] = '删除中,请稍候...';
$lang->instance->notices['adjusting'] = '调整中,请稍候...';
$lang->instance->notices['switching'] = '提交中,请稍候...';
$lang->instance->notices['setting'] = '提交中,请稍候...';
$lang->instance->notices['confirmInstall'] = '确定要安装(%s)?';
$lang->instance->notices['confirmUpgrade'] = '确定要升级到最新版吗?';
$lang->instance->notices['confirmBackup'] = '确定要备份吗?';
$lang->instance->notices['confirmRestore'] = '本操作将用备份的数据覆盖当前的数据,确定要回滚吗?';
$lang->instance->notices['confirmDelete'] = '确定要删除该备份数据吗?';
$lang->instance->notices['adjustMemory'] = '确定要调整中内存吗?';
$lang->instance->notices['switchLDAP'] = '修改LDAP会重启服务,确定要修改LDAP吗?';
$lang->instance->notices['enableLDAPFailed'] = '启用LDAP失败';
$lang->instance->notices['disableLDAPFailed'] = '禁用LDAP失败';
$lang->instance->notices['enableLDAPSuccess'] = '启用LDAP成功';
$lang->instance->notices['disableLDAPSuccess'] = '禁用LDAP成功';
$lang->instance->notices['switchSMTP'] = '修改SMTP会重启服务,确定要修改SMTP吗?';
$lang->instance->notices['enableSMTPFailed'] = '启用SMTP失败';
$lang->instance->notices['disableSMTPFailed'] = '禁用SMTP失败';
$lang->instance->notices['enableSMTPSuccess'] = '启用SMTP成功';
$lang->instance->notices['disableSMTPSuccess'] = '禁用SMTP成功';
$lang->instance->notices['confirmCustom'] = '修改自定义配置后服务将自动重启以使配置生效。';
$lang->instance->notices['required'] = '不能为空';
$lang->instance->nameChangeTo = ' %s 修改为 %s 。';
$lang->instance->versionChangeTo = ' %s 升级为 %s 。';
$lang->instance->toSeniorSerial = '从 %s 升级到 %s 。';
$lang->instance->adjustMemorySize = '建议调整内存到 %s 。';
$lang->instance->enableAutoBackup = '开启自动备份';
$lang->instance->disableAutoBackup = '关闭自动备份';
$lang->instance->instanceNotExists = '服务不存在';
$lang->instance->caplicasTooSmall = '副本数不能小于1';
$lang->instance->empty = '暂无服务';
$lang->instance->noComponent = '无组件,点击';
$lang->instance->noHigherVersion = '未找到更高版本!';
$lang->instance->backupOnlyRunning = '运行状态才能备份';
$lang->instance->restoreOnlyRunning = '运行状态才能回滚';
$lang->instance->howToSelectDB = '如何选择?';
$lang->instance->appLifeTip = 'demo账号安装的应用有30分钟限制,30分钟后自动删除。';
$lang->instance->serialDiff = '查看版本区别';
$lang->instance->descOfSwitchSerial = '您当前使用的是<strong>%s</strong>,想要体验更多高级功能,可升级至%s。';
$lang->instance->toSeniorAttention = '重要提示';
$lang->instance->toSeniorTips = "<ul class='text-danger'><li>版本升级后,无法回退到原版本。</li><li>企业版、旗舰版自安装后免费试用6个月。</li><li>开源版升级到企业版或旗舰版后,试用期最大支持3个用户,
请检查开源版用户数量。超出限制将不可用。</li><li>升级成功后,服务将自动重启。</li><li>为避免造成数据丢失,请您在升级前务必做好数据备份。</li></ul>";
$lang->instance->errors = new stdclass;
$lang->instance->errors->domainLength = '域名长度必须介于2-20字符之间';
$lang->instance->errors->domainExists = '域名已被占用,请使用其它域名。';
$lang->instance->errors->wrongDomainCharacter = '域名只能是小写英文字母和数字';
$lang->instance->errors->noAppInfo = '获取应用数据失败,请稍候重试。';
$lang->instance->errors->notEnoughResource = '集群资源不足';
$lang->instance->errors->notEnoughMemory = '%s 应用需要 %s 内存,当前可用内存%s ,还需要 %s,请扩充内存资源或删除其他服务后重试!';
$lang->instance->errors->restoreRunning = '当前回滚正在进行中,请等待当前回滚完成。';
$lang->instance->errors->noBackup = '无备份数据,';
$lang->instance->errors->wrongRequestData = '提交的数据有误,请刷新页面后重试。';
$lang->instance->errors->noDBList = '无数据库或不可访问';
$lang->instance->errors->notFoundDB = '找不到该数据库';
$lang->instance->errors->dbNameIsEmpty = '数据库名为空';
$lang->instance->errors->failToAdjustMemory = '调整内存失败';
$lang->instance->errors->switchLDAPFailed = '修改LDAP设置失败';
$lang->instance->errors->switchSMTPFailed = '修改SMTP设置失败';
$lang->instance->errors->updateCustomFailed = '修改自定义配置失败';
$lang->instance->errors->failToSenior = '升级到高级版失败';
$lang->instance->errors->failedToUpdateDomain = '更新域名失败';
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* The setting view file of instance module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Ke Zhao<zhaoke@easycorp.ltd>
* @package instance
* @link https://www.zentao.net
*/
namespace zin;
formPanel
(
set::id('instanceSettingForm'),
set::title($lang->instance->setting),
set::submitBtnText($lang->save),
set::actions(array('submit')),
formRow
(
formGroup
(
set::name('name'),
set::width('500px'),
set::label($lang->instance->name),
set::value($instance->name),
)
),
formRow
(
formGroup
(
set::name('memory_kb'),
set::width('250px'),
set::control('picker'),
set::label($lang->instance->adjustMem),
set::value(intval($currentResource->max->memory / 1024)),
set::items($this->instance->filterMemOptions($currentResource)),
)
),
);
+39
View File
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* The setting view file of instance module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Ke Zhao<zhaoke@easycorp.ltd>
* @package instance
* @link https://www.zentao.net
*/
namespace zin;
formPanel
(
set::id('instanceSettingForm'),
set::title(''),
set::submitBtnText($lang->confirm),
set::actions(array('submit', array('text' => $lang->cancel, 'data-type' => 'submit', 'data-dismiss' => 'modal'))),
span
(
setClass('p-4 font-semibold'),
icon('exclamation-sign', setClass('text-warning icon-2x align-middle m-2')),
$lang->instance->notices['confirmUpgrade'],
empty($instance->latestVersion->change_log_url) ? null: a
(
setClass('ml-5'),
set::target('_blank'),
set::href($instance->latestVersion->change_log_url),
setStyle('color', 'initial'),
setStyle('font-weight', 'initial'),
setStyle('text-decoration', 'underline'),
$lang->instance->updateLog,
),
),
div(setStyle('height', '20px')),
input(set::type('hidden'), set::name('confirm'), set::value('yes'))
);
+203
View File
@@ -0,0 +1,203 @@
<?php
declare(strict_types=1);
/**
* The appview view file of instance module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Ke Zhao<zhaoke@easycorp.ltd>
* @package instance
* @link http://www.zentao.net
*/
namespace zin;
jsVar('instanceID', $instance->id);
$setting = usePager('pager');
$cpuInfo = $this->instance->printCpuUsage($instance, $instanceMetric->cpu, 'array');
$memoryInfo = $this->instance->printMemUsage($instance, $instanceMetric->memory, 'array');
$actions = $this->loadModel('common')->buildOperateMenu($instance);
$dbListWg = array();
foreach($dbList as $db)
{
$disabledClass = $db->ready && commonModel::hasPriv('instance', 'ajaxDBAuthUrl') ? '' : 'disabled';
$dbListWg[] = h::tr
(
h::td($db->db_name),
h::td($db->db_type),
h::td
(
$db->ready ? $lang->instance->dbReady : $lang->instance->dbWaiting,
setClass('text-' . ($db->ready ? 'success' : 'danger'))
),
h::td
(
btn
(
$lang->instance->management,
setClass('btn text-primary ghost ' . $disabledClass),
setData('dbname', $db->name),
setData('dbtype', $db->db_type),
setData('id', $instance->id),
on::click('openAdminer'),
)
),
);
}
detailHeader(
to::prefix(''),
to::title(''),
);
div
(
setClass('flex flex-normal gap-x-5'),
div
(
setClass('basis-2/3'),
setID('instanceInfoContainer'),
detailBody
(
sectionList
(
/* 应用名称信息图标区块 */
section
(
div
(
setClass('flex justify-between'),
div
(
setClass('flex basis-full'),
img(set::src($instance->logo), setStyle(array('width' => '50px', 'height' => '50px'))),
div
(
setClass('ml-3 flex col gap-y-1 basis-full'),
div
(
$instance->name, setClass('text-xl'),
span($cloudApp->app_version, setClass('ml-3 label lighter rounded-full'))
),
div
(
setClass('flex progress-container'),
set::title($cpuInfo['tip']),
icon('cog-outline text-' . $cpuInfo['color']),
$lang->instance->cpuUsage,
div
(
setClass('progress rounded-lg'),
setStyle('background', "var(--color-{$cpuInfo['color']}-50)"),
div
(
setClass('progress-bar ' . $cpuInfo['color']),
set::role('progressbar'),
setStyle('width', $cpuInfo['rate'])
)
),
icon('desktop text-' . $memoryInfo['color']),
$lang->instance->memUsage,
span
(
setClass('text-gray'),
sprintf($lang->instance->memTotal, helper::formatKB($instanceMetric->memory->limit)),
),
div
(
setClass('progress rounded-lg'),
set::title($memoryInfo['tip']),
setStyle('background', "var(--color-{$memoryInfo['color']}-50)"),
div
(
setID('memoryRate'),
set::role('progressbar'),
setData('load', $instance->status == 'running' && $memoryInfo['rate'] == '0%'),
setClass('progress-bar ' . $memoryInfo['color']),
setStyle('width', $memoryInfo['rate'])
)
)
),
),
),
btn($lang->instance->setting, setClass('btn ghost'), set::icon('backend'), setData('toggle', 'modal'), setData('size', 'sm'), set::url(createLink('instance', 'setting', "id={$instance->id}")))
),
),
/* 基本信息区块 */
section
(
set::title($lang->instance->baseInfo),
h::table
(
setStyle('min-width', '700px'),
setClass('table w-auto max-w-full bordered mt-4'),
h::tr
(
h::th($lang->instance->status),
h::th($lang->instance->source),
// h::th($lang->instance->appTemplate),
h::th($lang->instance->installBy),
h::th($lang->instance->installAt),
h::th($lang->instance->runDuration),
$defaultAccount ? h::th($lang->instance->defaultAccount) : null,
$defaultAccount ? h::th($lang->instance->defaultPassword) : null,
),
h::tr
(
h::td
(
setID('statusTD'),
setData('reload', in_array($instance->status, array('creating', 'initializing', 'pulling', 'startup', 'starting', 'suspending', 'installing', 'uninstalling', 'stopping', 'destroying', 'upgrading'))),
span
(
setClass('label label-dot mr-1 ' . zget($this->lang->instance->htmlStatusesClass, $instance->status, ''))
),
zget($this->lang->instance->statusList, $instance->status, ''), setClass('text-' . zget($this->lang->instance->htmlStatusesClass, $instance->status, ''))
),
h::td(zget($lang->instance->sourceList, $instance->source, '')),
// h::td(a(set::href($this->createLink('store', 'appView', "id=$instance->appID")), $instance->appName)),
h::td(zget($users, $instance->createdBy, '')),
h::td(substr($instance->createdAt, 0, 16)),
h::td(common::printDuration($instance->runDuration)),
$defaultAccount ? h::td($defaultAccount->username) : null,
$defaultAccount ? h::td($defaultAccount->password) : null,
)
)
),
/* 数据库区块 */
empty($dbList) ? null : section
(
set::title($lang->instance->dbList),
h::table
(
setStyle('min-width', '700px'),
setClass('table w-auto max-w-full bordered mt-4'),
h::tr
(
h::th($lang->instance->dbName),
h::th($lang->instance->dbType, setStyle('width', '100px')),
h::th($lang->instance->status, setStyle('width', '100px')),
h::th($lang->instance->action, setStyle('width', '100px')),
),
$dbListWg
)
),
),
floatToolbar
(
set::object($instance),
isAjaxRequest('modal') ? null : to::prefix(backBtn(set::icon('back'), set::class('ghost text-white'), $lang->goback)),
set::main($actions['mainActions']),
set::suffix($actions['suffixActions'])
),
)
),
div
(
setClass('basis-auto'),
history()
)
);
+192
View File
@@ -0,0 +1,192 @@
<div class='panel'>
<?php $ips = (array) zget($domain,'load_balancer_ips', new stdclass);?>
<?php if(!empty($ips)):?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->instance->visitIP;?></span></div>
</div>
<div class='panel-body'>
<table class='table table-form cell'>
<?php foreach($ips as $key => $value):?>
<tr>
<th><?php echo $key;?></th>
<td><?php echo $value;?></td>
</tr>
<?php endforeach;?>
</table>
</div>
<?php endif;?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->instance->mem;?></span></div>
</div>
<div class='panel-body'>
<form id='memoryForm' class='cell not-watch load-indicator'>
<table class='table table-form'>
<tr>
<th></th>
<td colspan="3">
<span class='label label-info'><?php echo $lang->instance->currentMemory;?>:<?php echo helper::formatKB($currentResource->resources->memory / 1024);?></span>
<span class='label label-warning'><?php $this->instance->printSuggestedMemory($instanceMetric->memory, $lang->instance->memOptions);?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->instance->adjustMem;?></th>
<td class='w-100px'><?php echo html::select('memory_kb', $this->instance->filterMemOptions($currentResource), '', "class='form-control'");?></td>
<td></td>
<td></td>
</tr>
<tr>
<th></th>
<td class='text-center'>
<?php echo html::commonButton($lang->instance->saveSetting, "id='memBtn' instance-id='$instance->id'", 'btn btn-primary'); ?>
</td>
<td></td>
<td></td>
</tr>
</table>
</form>
</div>
<?php if(isset($cloudApp->features->ldap)):?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->system->ldapManagement;?></span></div>
</div>
<div class='panel-body'>
<form id='LDAPForm' class='cell not-watch load-indicator'>
<table class='table table-form'>
<tr>
<?php $LDAPInstalled = $this->system->hasSystemLDAP();?>
<?php $enableLDAP = $instance->ldapSnippetName ? 'true' : '' ;?>
<td class='w-120px'><?php echo html::checkbox('enableLDAP', array('true' => $lang->instance->enableLDAP), $enableLDAP, ($LDAPInstalled ? '' : 'disabled'));?></td>
<td colspan='2'>
<?php if(!$LDAPInstalled):?>
<?php echo $lang->instance->systemLDAPInactive;?>
<?php echo html::a(helper::createLink('system', 'installLDAP'), $lang->instance->toSystemLDAP, '', "class='btn btn-default'");?>
<?php endif?>
</td>
<td></td>
</tr>
<tr>
<th></th>
<td class='w-100px text-center'>
<?php echo html::commonButton($lang->instance->saveSetting, "id='ldapBtn' instance-id='$instance->id'" . ($LDAPInstalled ? '' : 'disabled'), 'btn btn-primary');?>
</td>
<td></td>
<td></td>
</tr>
</table>
</form>
</div>
<?php endif;?>
<?php if(isset($cloudApp->features->mail)):?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->system->SMTP->common;?></span></div>
</div>
<div class='panel-body'>
<form id='SMTPForm' class='cell not-watch load-indicator'>
<table class='table table-form'>
<tr>
<?php $SMTPInstalled = $this->system->isSMTPEnabled();?>
<?php $enableSMTP = $instance->smtpSnippetName ? 'true' : '' ;?>
<td class='w-120px'><?php echo html::checkbox('enableSMTP', array('true' => $lang->instance->enableSMTP), $enableSMTP, ($SMTPInstalled ? '' : 'disabled'));?></td>
<td colspan='2'>
<?php if(!$SMTPInstalled):?>
<?php echo $lang->instance->systemSMTPInactive;?>
<?php echo html::a(helper::createLink('system', 'installSMTP'), $lang->instance->toSystemSMTP, '', "class='btn btn-default'");?>
<?php endif?>
</td>
<td></td>
</tr>
<tr>
<th></th>
<td class='w-100px text-center'>
<?php echo html::commonButton($lang->instance->saveSetting, "id='smtpBtn' instance-id='$instance->id'" . ($SMTPInstalled ? '' : 'disabled'), 'btn btn-primary');?>
</td>
<td></td>
<td></td>
</tr>
</table>
</form>
</div>
<?php endif;?>
<?php if(!empty($currentResource->scalable) && $config->edition == 'biz'):?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->instance->scalable;?></span></div>
</div>
<div class='panel-body'>
<form id='replicasForm' class='cell not-watch load-indicator'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->instance->componentFields['replicas'];?></th>
<td class='w-80px center'>
<span id="replicas-text"><?php echo $currentResource->replicas;?></span>
<?php echo html::select('scalable', array(1=>1, 2=>2, 3=>3, 4=>4), intval($currentResource->replicas) ? : 1, " id='replicas-input' max='4' min='1' class='form-control scalable-input hide'");?>
</td>
<td>
<?php echo html::commonButton($lang->instance->change, 'id="replicas-edit"', 'btn btn-primary ' . (in_array($instance->status, array('uninstalling', 'destroying', 'destroyed', 'unknown', 'abnormal')) ? 'disabled' : ''));?>
<?php echo html::commonButton($lang->instance->saveSetting, "id='replicas-save' instance-id='$instance->id'", 'btn btn-primary hide');?>
</td>
<td></td>
</tr>
</table>
</form>
</div>
<?php endif;?>
<?php if(count($customItems)):?>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->instance->customSetting;?></span></div>
</div>
<div class='panel-body'>
<form id='customForm' class='cell not-watch load-indicator'>
<table class='table table-form'>
<?php foreach($customItems as $item):?>
<tr>
<th><?php echo $item->label;?></th>
<td>
<?php echo html::input($item->name, $item->default, "class='form-control' placeholder='{$item->label}'");?>
</td>
<td></td>
<td></td>
</tr>
<?php endforeach;?>
<tr>
<th></th>
<td class='text-center'>
<?php echo html::commonButton($lang->instance->saveSetting, "id='customBtn' instance-id='$instance->id'", 'btn btn-primary'); ?>
</td>
<td></td>
<td></td>
</tr>
</table>
</form>
</div>
<?php endif;?>
<?php if(!empty($dbList)):?>
<hr/>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->instance->dbList;?></div>
</div>
<div class='panel-body'>
<table class='table table-bordered text-center'>
<thead>
<tr>
<th><?php echo $lang->instance->dbName;?></th>
<th><?php echo $lang->instance->dbType;?></th>
<th><?php echo $lang->instance->dbStatus;?></th>
<th><?php echo $lang->instance->action;?></th>
</tr>
</thead>
<tbody>
<?php foreach($dbList as $db):?>
<tr>
<td><?php echo $db->db_name;?></td>
<td><?php echo $db->db_type;?></td>
<td><?php echo $db->ready ? $lang->instance->dbReady : $lang->instance->dbWaiting;?></td>
<td><?php $this->instance->printDBAction($db, $instance);?></td>
<tr>
<?php endforeach;?>
<tbody>
</table>
</div>
<?php endif;?>
</div>
+80
View File
@@ -0,0 +1,80 @@
<div class='panel'>
<div class='panel-heading'>
<span class='text-blue'><?php echo $lang->instance->backup->keepBackupBySystem;?></span>
<div class='btn-toolbar pull-right'>
<?php echo html::a(".", $lang->refresh, '', "class='btn'");?>
<?php $autoBackupBtn = html::a(helper::createLink('instance', 'backupSettings', "id={$instance->id}", '', true), $lang->instance->backup->autoBackup, '', "class='iframe btn btn-primary' title='{$lang->instance->backup->autoBackup}' data-width='520' data-app='space'");?>
<?php $autoRestoreBtn = html::a(helper::createLink('instance', 'restoreSettings', "id={$instance->id}", '', true), $lang->instance->restore->autoRestore, '', "class='iframe btn btn-primary' title='{$lang->instance->restore->autoRestore}' data-width='520' data-app='space'");?>
<?php echo $this->config->instance->enableAutoRestore ? $autoRestoreBtn : $autoBackupBtn;?>
<?php $this->instance->printBackupBtn($instance);?>
</div>
</div>
<?php if(empty($backupList)):?>
<div class="table-empty-tip">
<p>
<?php echo $lang->instance->errors->noBackup;?>
<?php $this->instance->printBackupBtn($instance);?>
</p>
</div>
<?php else:?>
<table class="table table-bordered text-center">
<thead>
<tr>
<th class='w-150px'><?php echo $lang->instance->backup->date;?></th>
<th class='w-150px'><?php echo $lang->instance->backup->operator;?></th>
<th class='w-150px'><?php echo $lang->instance->backup->dbStatus;?></th>
<th class='w-150px'><?php echo $lang->instance->backup->dbSize;?></th>
<?php if($hasRestoreLog):?>
<th class='w-150px'><?php echo $lang->instance->backup->restoreDate;?></th>
<th class='w-150px'><?php echo $lang->instance->backup->dbStatus;?></th>
<?php endif;?>
<th class="w-150px actions">
<?php echo $lang->instance->backup->action;?>
</th>
</tr>
</thead>
<tbody>
<?php foreach($backupList as $backup):?>
<tr>
<td><span data-toggle='tooltip' data-placement='bottom' title='<?php echo date('Y-m-d H:i:s', $backup->create_time);?>'><?php echo date('Y-m-d', $backup->create_time);?></span></td>
<td><?php echo zget($lang->instance->backup->operators, $backup->username, $backup->username);?></td>
<td><?php echo zget($lang->instance->backup->statusList, strtolower($backup->status));?></td>
<?php $backupSize = isset($backup->backup_details->db[0]) ? intval(zget($backup->backup_details->db[0], 'size', 0)) : 0;?>
<?php $backupSize += isset($backup->backup_details->volume[0]) ? intval(zget($backup->backup_details->volume[0], 'doneBytes', 0)) : 0;?>
<td><?php echo helper::formatKB($backupSize / 1024);?></td>
<?php if($hasRestoreLog):?>
<td>
<span data-toggle='tooltip' data-placement='bottom' title='<?php echo $backup->latest_restore_time ? date('Y-m-d H:i:s', $backup->latest_restore_time) : '';?>'>
<?php echo $backup->latest_restore_time ? date('Y-m-d', $backup->latest_restore_time) : '';?>
</span>
</td>
<td><?php echo $backup->latest_restore_status ? zget($lang->instance->restore->statusList, $backup->latest_restore_status, '') : '';?></td>
<?php endif;?>
<td><?php $this->instance->printRestoreBtn($instance, $backup);?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class="modal fade" id="confirmRestore" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog w-400px">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
<h2 class="text-center"><?php echo $lang->instance->backup->restore;?></h2>
<div class="text-center confirm-text">
<p class='modal-message text-center'><?php echo $lang->instance->backup->backupBeforeRestore;?></p>
<p class='modal-message text-center'>
<?php echo $lang->instance->backup->latestBackupAt;?>:
<?php echo date('Y-m-d H:i:s', $latestBackup->create_time);?>
</p>
</div>
<div class="text-center">
<?php echo html::commonButton($lang->instance->backup->common, "instance-id='{$instance->id}'", 'btn-backup btn btn-wide');?>
<?php echo html::commonButton($lang->instance->backup->restore, "id='submitRestore'", 'btn btn-primary btn-wide');?>
</div>
</div>
</div>
</div>
</div>
<?php endif;?>
</div>
@@ -0,0 +1,59 @@
<?php
/**
* The auto backup view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.cn)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.cn
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php include $this->app->getModuleRoot() . '/common/view/datepicker.html.php';?>
<?php js::set('instanceNotices', $lang->instance->notices);?>
<?php js::set('instanceID', $instance->id);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->instance->backup->autoBackup;?></h2>
</div>
<div>
<form id='backupSettingForm' method='post' class="cell not-watch load-indicator main-form">
<h4><?php echo html::checkbox('autoBackup', array('true' => $lang->instance->backup->enableAutoBackup), $backupSettings->autoBackup ? 'true' : '');?></h4>
<table class="table table-form backup-settings">
<tbody>
<tr>
<th><?php echo $lang->instance->backup->backupTime;?></th>
<td class='required'>
<div class='input-group'>
<div class='datepicker-wrapper datepicker-date'>
<?php echo html::input('backupTime', $backupSettings->backupTime, "class='form-control form-time' data-picker-position='bottom-right' maxlength='20'");?>
</div>
</div>
</td>
<td></td>
</tr>
<tr>
<th class='w-80px'><?php echo $lang->instance->backup->cycleDays;?></th>
<td class='required w-250px'>
<div class='input-group'><?php echo html::select('cycleDays', $lang->instance->backup->cycleList, $backupSettings->cycleDays, "class='form-control' maxlength='20'");?></div>
</td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->instance->backup->keepDays;?></th>
<td class='required'>
<div class='input-group'><?php echo html::number('keepDays', $backupSettings->keepDays, "class='form-control' maxlength='2' min='1' max='30'");?></div>
<span><?php echo $lang->instance->backup->keepDayRange;?></span>
</td>
<td></td>
</tr>
</tbody>
</table>
<div class="text-center form-actions"><?php echo html::commonButton($lang->save, "id='saveSetting'", 'btn btn-primary');?></div>
</form>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+115
View File
@@ -0,0 +1,115 @@
<div>
<div class="panel">
<div class="panel-body">
<div class="row">
<div class="col col-4">
<table class="table table-data">
<tbody>
<tr>
<th><?php echo $lang->instance->status;?></th>
<td class="instance-status" instance-id="<?php echo $instance->id;?>" data-status="<?php echo $instance->status;?>">
<?php echo $this->instance->printStatus($instance, false);?>
</td>
</tr>
<tr>
<th><?php echo $lang->instance->source;?></th>
<td class="instance-source">
<span><?php echo zget($lang->instance->sourceList, $instance->source, '');?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->instance->appTemplate;?></th>
<td><?php echo html::a($this->createLink('store', 'appView', "id=$instance->appID"), $instance->appName);?></td>
</tr>
<tr>
<th><?php echo $lang->instance->installAt;?></th>
<td><span><?php echo substr($instance->createdAt, 0, 16);?></span></td>
</tr>
<?php if($instance->status == 'running'):?>
<tr>
<th><?php echo $lang->instance->runDuration;?></th>
<td><?php echo common::printDuration($instance->runDuration);?></td>
</tr>
<?php endif;?>
<?php if($defaultAccount):?>
<tr>
<th><?php echo $lang->instance->defaultAccount;?></th>
<td><?php echo $defaultAccount->username;?></td>
</tr>
<tr>
<th><?php echo $lang->instance->defaultPassword;?></th>
<td><?php echo $defaultAccount->password;?></td>
</tr>
<?php endif;?>
</tbody>
</table>
</div>
<div class='col col-8 usage-box'>
<div class='col col-6'>
<div class="c-title"><?php echo $lang->instance->cpuUsage;?></div>
<?php $this->instance->printCpuUsage($instance, $instanceMetric->cpu, 'pie');?>
</div>
<div class='col col-6'>
<div class="c-title"><?php echo $lang->instance->memUsage;?></div>
<?php $this->instance->printMemUsage($instance, $instanceMetric->memory, 'pie');?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php if(empty($instance->solution) && array_key_exists(strtolower($instance->chart), $this->config->instance->seniorChartList)):?>
<div id='seniorAppPanel' class="panel">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->instance->upgradeToSenior;?></div>
</div>
<div class="panel-body">
<p id='senior-app-desc'>
<?php $seniorAppHtml = '';?>
<?php foreach($seniorAppList as $number => $seniorApp):?>
<?php if($number > 0) $seniorAppHtml .= $lang->instance->or;?>
<?php $seniorAppHtml .= html::a(helper::createLink('store', 'appview', "id=$seniorApp->id"), $seniorApp->alias, '_blank');?>
<?php endforeach;?>
<?php $currentAppUrl = html::a(helper::createLink('store', 'appview', "id=$instance->appID"), $instance->appName, '_blank');?>
<?php printf($lang->instance->descOfSwitchSerial, $currentAppUrl, $seniorAppHtml);?>
<?php echo html::a('https://www.zentao.net/page/enterprise.html', $lang->instance->serialDiff, '_blank', "id='serialDiff' class=''");?>
</p>
<div>
<?php $disabled = $instance->status == 'stopped' ? '' : 'disabled';?>
<?php foreach($seniorAppList as $seniorApp):?>
<?php $toSeniorUrl = $this->inLink('toSenior', "id={$instance->id}&seniorAppID={$seniorApp->id}", '', true);?>
<?php echo html::a($toSeniorUrl, $lang->instance->switchTo . $seniorApp->alias, '', $disabled . " class='iframe btn btn-primary' title='{$lang->instance->upgrade}' data-width='520' data-app='space'");?>
<?php endforeach;?>
<?php if($disabled == 'disabled'):?>
<span class='text-info'><?php echo $lang->instance->stopInstanceTips;?></span>
<?php endif;?>
</div>
</div>
</div>
<?php endif;?>
<div class="panel instance-log">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->instance->operationLog;?></div>
</div>
<div class="panel-body">
<table class="table table-borderless">
<thead>
<tr>
<th class="w-180px"><?php echo $lang->instance->log->date;?></th>
<th><?php echo $lang->instance->log->message;?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach($logs as $log):?>
<tr>
<td><?php echo $log->date;?></td>
<td><?php echo $this->instance->printLog($instance, $log);?></td>
<td></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<div class="table-footer"><?php $pager->show('right', 'pagerjs');?></div>
</div>
</div>
@@ -0,0 +1,69 @@
<?php
/**
* The custom install view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.com)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.com
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<div id='mainMenu' class='clearfix'>
<div class="btn-toolbar pull-left">
<?php echo html::a($this->createLink('store', 'appView', "id={$appID}"), '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-secondary'");?>
</div>
</div>
<div id='mainContent' class='main-row'>
<form class="cell load-indicator main-form form-ajax" method='post'>
<h3><?php echo $lang->instance->customInstall;?></h3>
<?php if(empty($components)):?>
<div class="table-empty-tip">
<p><?php echo html::a($this->createLink('store', 'appView', "id={$appID}"), $lang->instance->noComponent . '<i class="icon icon-back icon-sm"></i> ' . $lang->goback, '', "class='btn btn-info'");?></p>
</div>
<?php endif?>
<ul class="nav nav-tabs">
<?php foreach($components as $component):?>
<li class="<?php echo$activeTab == $component->name ? 'active' : '';?>">
<a data-tab href="#<?php echo $component->name;?>"><?php echo $component->name;?></a>
</li>
<?php endforeach?>
</ul>
<div class="tab-content">
<?php foreach($components as $component):?>
<div class="tab-pane <?php echo$activeTab == $component->name ? 'active' : '';?>" id="<?php echo $component->name;?>">
<table class="table table-form">
<tbody>
<?php foreach($component->settings as $setting):?>
<?php
if($setting->type == 'choice')
{
$selectOptions = array_combine($setting->options, $setting->options);
if(strpos($setting->field, 'resources_cpu') !== false) $selectOptions = $this->instance->getCpuOptions($setting->options);
if(strpos($setting->field, 'resources_memory') !== false) $selectOptions = $this->instance->getMemOptions($setting->options);
}
?>
<tr>
<th class='w-150px'><?php echo zget($this->lang->instance->componentFields, $setting->name, $setting->name);?></th>
<td class='w-200px'>
<div class='input-group'>
<?php if($setting->type == 'choice') echo html::select($setting->field, $selectOptions, $setting->value, "class='form-control chosen'");?>
<?php if($setting->type == 'int') echo html::number($setting->field, $setting->value, "class='form-control'", "require");?>
</div>
</td>
<td></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endforeach;?>
<?php if(!empty($components)):?>
<div class="text-center form-actions"><?php echo html::submitButton($lang->instance->install);?></div>
<?php endif;?>
</div>
</form>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+28
View File
@@ -0,0 +1,28 @@
<?php
/**
* The edit view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.com)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.com
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<h2><?php echo $lang->instance->editName;?></h2>
</div>
<form method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->instance->name;?></th>
<td><?php echo html::input('name', $instance->name, "class='form-control' maxlength='50'");?></td>
</tr>
</table>
<div class='text-center form-actions'><?php echo html::submitButton() . html::backButton();?></div>
</form>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+118
View File
@@ -0,0 +1,118 @@
<?php
/**
* The install view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.cn)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.cn
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php js::set('instanceNotices', $lang->instance->notices);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->instance->installApp . $cloudApp->alias . $cloudApp->app_version;?></h2>
</div>
<form id='installForm' action='<?php echo helper::createLink("instance", "install", "id={$cloudApp->id}", '', '', false);?>' class="cell not-watch load-indicator main-form">
<table class="table table-form">
<tbody>
<tr>
<th class='w-80px'><?php echo $lang->instance->name;?></th>
<td class='w-250px'>
<div class='input-group'>
<?php echo html::input('customName', $cloudApp->alias, "class='form-control' maxlength='20'");?>
</div>
</td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->instance->domain;?></th>
<td>
<div class='input-group'>
<?php echo html::input('customDomain', $thirdDomain, "class='form-control' maxlength='20'");?>
<span class='input-group-addon'><?php echo $this->cne->sysDomain();?></span>
</div>
</td>
<td></td>
</tr>
</tbody>
</table>
<div class='advanced'><?php echo html::a("#advanced-settings", $lang->instance->advanceOption . "<i class='icon icon-chevron-double-down'></i>", '', "data-toggle='collapse'");?></div>
<table class="collapse table table-form" id="advanced-settings">
<tbody>
<?php if(strtolower(getenv('ALLOW_SELECT_VERSION')) == 'true' || strtolower(getenv('ALLOW_SELECT_VERSION')) == '1'):?>
<tr>
<th class='w-80px'><?php echo $lang->instance->version;?></th>
<td class='w-250px'>
<div class='input-group'>
<?php echo html::select('version', $versionList, '', "class='form-control'");?>
</div>
</td>
<td></td>
</tr>
<?php endif;?>
<?php if(isset($cloudApp->features->ldap) && $this->loadModel('system')->hasSystemLDAP()):?>
<tr>
<th class='w-80px'></th>
<td class='w-250px'>
<div class='input-group'>
<?php echo html::checkbox('ldapSnippet', array($this->system->ldapSnippetName() => $lang->instance->enableLDAP));?>
</div>
</td>
<td></td>
</tr>
<?php endif;?>
<?php if(isset($cloudApp->features->mail) && $this->loadModel('system')->isSMTPEnabled()):?>
<tr>
<th class='w-80px'></th>
<td class='w-250px'>
<div class='input-group'>
<?php echo html::checkbox('smtpSnippet', array($this->system->smtpSnippetName() => $lang->instance->enableSMTP));?>
</div>
</td>
<td></td>
</tr>
<?php endif;?>
<?php if(isset($cloudApp->dependencies->mysql) and $mysqlList or isset($cloudApp->dependencies->postgresql) and $pgList):?>
<tr>
<th class='w-80px'><?php echo $lang->instance->dbType;?></th>
<td class='w-250px'>
<div class='input-group'>
<?php echo html::radio('dbType', $lang->instance->dbTypes, 'sharedDB');?>
</div>
</td>
<td><?php echo html::a('https://www.qucheng.com/book/Installation-manual/app-install-33.html',$lang->instance->howToSelectDB, '_blank');?></td>
</tr>
<?php endif;?>
<?php if(isset($cloudApp->dependencies->mysql) and $mysqlList):?>
<tr>
<th></th>
<td>
<div class='input-group'>
<?php echo html::select('dbService', $mysqlList, '', "class='form-control'");?>
</div>
</td>
<td></td>
</tr>
<?php elseif(isset($cloudApp->dependencies->postgresql) and $pgList):?>
<tr>
<th></th>
<td>
<div class='input-group'>
<?php echo html::select('dbService', $pgList, '', "class='form-control'");?>
</div>
</td>
<td></td>
</tr>
<?php endif;?>
</tbody>
</table>
<div class="text-center form-actions"><?php echo html::submitButton($lang->instance->install);?></div>
</form>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
@@ -0,0 +1,22 @@
<?php
/**
* The custom install view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.cn)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.cn
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->instance->errors->notEnoughResource;?></h2>
</div>
<div><p style='padding-top: 15px;'><?php echo sprintf($lang->instance->errors->notEnoughMemory, $cloudApp->alias, $requiredMemory, $freeMemory, $gapMemory);?></p></div>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
@@ -0,0 +1,55 @@
<?php
/**
* The restore settings view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.cn)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.cn
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php include $this->app->getModuleRoot() . '/common/view/datepicker.html.php';?>
<?php js::set('instanceNotices', $lang->instance->notices);?>
<?php js::set('instanceID', $instance->id);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->instance->restore->autoRestore;?></h2>
</div>
<div>
<form id='restoreSettingForm' method='post' class="cell not-watch load-indicator main-form">
<h4>
<?php echo html::checkbox('autoRestore', array('true' => $lang->instance->restore->enableAutoRestore), $restoreSettings->autoRestore ? 'true' : '');?>
</h4>
<table class="table table-form restore-settings">
<tbody>
<tr>
<th><?php echo $lang->instance->restore->restoreTime;?></th>
<td class='required'>
<div class='input-group'>
<div class='datepicker-wrapper datepicker-date'>
<?php echo html::input('restoreTime', $restoreSettings->restoreTime, "class='form-control form-time' data-picker-position='bottom-right' maxlength='20'");?>
</div>
</div>
</td>
<td></td>
</tr>
<tr>
<th class='w-80px'><?php echo $lang->instance->restore->cycleDays;?></th>
<td class='required w-250px'>
<div class='input-group'>
<?php echo html::select('cycleDays', $lang->instance->restore->cycleList, $restoreSettings->cycleDays, "class='form-control' maxlength='20'");?>
</div>
</td>
<td></td>
</tr>
</tbody>
</table>
<div class="text-center form-actions"><?php echo html::commonButton($lang->save, "id='saveSetting'", 'btn btn-primary');?></div>
</form>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+28
View File
@@ -0,0 +1,28 @@
<?php
/**
* The upgrade to senior App view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.cn)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.cn
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<h2><?php echo $lang->instance->toSeniorAttention;?></h2>
</div>
<div>
<form id='toSeniorForm' action="<?php echo $this->inLink('toSenior', "instanceID={$instance->id}&seniorAppID={$cloudApp->id}&confirm=yes");?>" class="cell not-watch load-indicator main-form form-ajax">
<div><?php echo $lang->instance->toSeniorTips;?></div>
<div>
<?php echo html::checkbox('read', array('true'=>$lang->instance->hasRead));?>
</div>
<div class="text-center form-actions"><?php echo html::submitButton($lang->instance->upgrade, 'disabled');?></div>
</form>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+32
View File
@@ -0,0 +1,32 @@
<?php
/**
* The edit view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QurCheng Software Co,LTD, www.qucheng.com)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.com
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php js::set('instanceNotices', $lang->instance->notices);?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<h2><?php echo "{$lang->instance->upgrade} : {$instance->name}";?></h2>
</div>
<form method='post' action='<?php echo helper::createLink("instance", "upgrade", "id=$instance->id");?>' id='upgradeForm'>
<?php if(empty($instance->latestVersion)):?>
<p class='modal-message text-center'><?php echo $lang->instance->noHigherVersion;?></p>
<?php else:?>
<p class='modal-message text-center'><?php echo $lang->instance->notices['confirmUpgrade'];?></p>
<?php echo html::hidden('confirm', 'yes');?>
<div class='text-center'>
<button type="button" class="btn btn-default btn-wide" data-dismiss="modal"><?php echo $lang->cancel;?></button>
<?php echo html::submitButton($lang->instance->upgrade);?>
</div>
<?php endif;?>
</form>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
+50
View File
@@ -0,0 +1,50 @@
<?php
/**
* The detail view file of instance module of QuCheng.
*
* @copyright Copyright 2021-2022 北京渠成软件有限公司(BeiJing QuCheng Software Co,LTD, www.qucheng.com)
* @license ZPL (http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jianhua Wang <wangjianhua@easycorp.ltd>
* @package instance
* @version $Id$
* @link https://www.qucheng.com
*/
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php js::set('instanceNotices', $lang->instance->notices);?>
<?php js::set('instanceIdList', array($instance->id));?>
<?php js::set('demoAppLife', $config->demoAppLife);?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left instance-name'>
<h3><?php echo $instance->name;?></h3>
<span><?php echo $instance->appVersion;?></span>
<?php echo html::a($this->createLink('instance', 'editname', "id=$instance->id", '', true), '<i class="icon-edit"></i>', '', "class='iframe' title='$lang->edit' data-width='600' data-app='space'");?>
<?php if($instance->solution):?>
<?php echo html::a(helper::createLink('solution', 'view', "id=$instance->solution"), $instance->solutionData->name, '', "class='label label-success label-outline solution-link'");?>
<?php endif;?>
</div>
<div class='btn-toolbar pull-right instance-panel'>
<div class="">
<?php $this->instance->printTextActions($instance);?>
</div>
</div>
</div>
<div id='mainContent' class='main-row'>
<ul class="nav nav-tabs">
<li class="<?php echo $tab == 'baseinfo' ? 'active' : '';?>"><a href="<?php echo $this->createLink('instance', 'view', "id=$instance->id&page=&perPage=&pageSize=&tab=baseinfo");?>"><?php echo $lang->instance->baseInfo;?></a></li>
<li class="<?php echo $tab == 'backup' ? 'active' : '';?>"><a href="<?php echo $this->createLink('instance', 'view', "id={$instance->id}&total=&perPage=&pageID=&tab=backup");?>"><?php echo $lang->instance->backupAndRestore;?></a></li>
<li class="<?php echo $tab == 'advance' ? 'active' : '';?>"><a href="<?php echo $this->createLink('instance', 'view', "id={$instance->id}&total=&perPage=&pageID=&tab=advance");?>"><?php echo $lang->instance->advance;?></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane <?php echo $tab == 'baseinfo' ? 'active' : '';?>" id="baseInfo">
<?php include 'baseinfo.html.php';?>
</div>
<div class="tab-pane <?php echo $tab == 'backup' ? 'active' : '';?>" id="backup">
<?php if($tab == 'backup') include 'backup.html.php';?>
</div>
<div class="tab-pane <?php echo $tab == 'advance' ? 'active' : '';?>" id="advance">
<?php if($tab == 'advance') include 'advance.html.php';?>
</div>
</div>
</div>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>