mirror of https://github.com/MISP/MISP
commit
fc8f7982df
|
@ -308,11 +308,48 @@ class AdminShell extends AppShell
|
|||
}
|
||||
|
||||
public function updateDatabase() {
|
||||
echo 'Executing all updates to bring the database up to date with the current version.' . PHP_EOL;
|
||||
$this->Server->runUpdates(true);
|
||||
echo 'All updates completed.' . PHP_EOL;
|
||||
$whoami = exec('whoami');
|
||||
if ($whoami === 'httpd' || $whoami === 'www-data') {
|
||||
echo 'Executing all updates to bring the database up to date with the current version.' . PHP_EOL;
|
||||
$this->Server->runUpdates(true);
|
||||
echo 'All updates completed.' . PHP_EOL;
|
||||
} else {
|
||||
die('This OS user is not allowed to run this command.'. PHP_EOL. 'Run it under `www-data` or `httpd`.' . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateApp() {
|
||||
$whoami = exec('whoami');
|
||||
if ($whoami === 'httpd' || $whoami === 'www-data') {
|
||||
$command = $this->args[0];
|
||||
if (!empty($this->args[1])) {
|
||||
$processId = $this->args[1];
|
||||
$job = $this->Job->read(null, $processId);
|
||||
} else { // create worker
|
||||
$this->Job->create();
|
||||
$job_data = array(
|
||||
'worker' => 'prio',
|
||||
'job_type' => 'update_app',
|
||||
'job_input' => 'command: ' . $command,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org_id' => '',
|
||||
'org' => '',
|
||||
'message' => 'Updating.',
|
||||
);
|
||||
$this->Job->save($job_data);
|
||||
$job = $this->Job->read(null, $this->Job->id);
|
||||
}
|
||||
$result = $this->Server->updateDatabase($command, false);
|
||||
$job['Job']['progress'] = 100;
|
||||
$job['Job']['message'] = 'Update done';
|
||||
$this->Job->save($job);
|
||||
} else {
|
||||
die('This OS user is not allowed to run this command.'. PHP_EOL. 'Run it under `www-data` or `httpd`.' . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getAuthkey() {
|
||||
if (empty($this->args[0])) {
|
||||
echo 'Invalid parameters. Usage: ' . APP . 'Console/cake Admin getAuthkey [user_email]' . PHP_EOL;
|
||||
|
@ -404,7 +441,7 @@ class AdminShell extends AppShell
|
|||
}
|
||||
echo 'Updated, new key:' . PHP_EOL . $authKey . PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
public function getOptionParser() {
|
||||
$parser = parent::getOptionParser();
|
||||
$parser->addSubcommand('updateJSON', array(
|
||||
|
|
|
@ -446,4 +446,5 @@ class ServerShell extends AppShell
|
|||
$this->Task->id = $task['Task']['id'];
|
||||
$this->Task->saveField('message', count($servers) . ' job(s) completed at ' . date('d/m/Y - H:i:s') . '.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -372,7 +372,7 @@ class AppController extends Controller
|
|||
$this->Auth->logout();
|
||||
throw new MethodNotAllowedException($message);//todo this should pb be removed?
|
||||
} else {
|
||||
$this->Flash->error('Warning: MISP is currently disabled for all users. Enable it in Server Settings (Administration -> Server Settings -> MISP tab -> live)', array('clear' => 1));
|
||||
$this->Flash->error('Warning: MISP is currently disabled for all users. Enable it in Server Settings (Administration -> Server Settings -> MISP tab -> live). An update might also be in progress, you can see the progress in ' , array('params' => array('url' => $baseurl . '/servers/advancedUpdate/', 'urlName' => 'Advanced Update'), 'clear' => 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,7 +835,11 @@ class AppController extends Controller
|
|||
}
|
||||
$this->Server->updateDatabase($command);
|
||||
$this->Flash->success('Done.');
|
||||
$this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration'));
|
||||
if ($liveOff) {
|
||||
$this->redirect(array('controller' => 'servers', 'action' => 'updateProgress'));
|
||||
} else {
|
||||
$this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration'));
|
||||
}
|
||||
}
|
||||
|
||||
public function upgrade2324()
|
||||
|
|
|
@ -340,6 +340,7 @@ class ACLComponent extends Component
|
|||
'getSubmoduleQuickUpdateForm' => array('perm_site_admin'),
|
||||
'getVersion' => array('*'),
|
||||
'index' => array('OR' => array('perm_sync', 'perm_admin')),
|
||||
'ondemandAction' => array(),
|
||||
'postTest' => array('perm_sync'),
|
||||
'previewEvent' => array(),
|
||||
'previewIndex' => array(),
|
||||
|
@ -359,6 +360,7 @@ class ACLComponent extends Component
|
|||
'testConnection' => array('perm_sync'),
|
||||
'update' => array(),
|
||||
'updateJSON' => array(),
|
||||
'updateProgress' => array(),
|
||||
'updateSubmodule' => array(),
|
||||
'uploadFile' => array(),
|
||||
'clearWorkerQueue' => array()
|
||||
|
|
|
@ -1545,6 +1545,69 @@ class ServersController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function ondemandAction()
|
||||
{
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
throw new MethodNotAllowedException('You are not authorised to do that.');
|
||||
}
|
||||
$this->AdminSetting = ClassRegistry::init('AdminSetting');
|
||||
$actions = $this->Server->actions_description;
|
||||
$default_fields = array(
|
||||
'title' => '',
|
||||
'description' => '',
|
||||
'liveOff' => false,
|
||||
'recommendBackup' => false,
|
||||
'exitOnError' => false,
|
||||
'requirements' => '',
|
||||
'url' => '/'
|
||||
);
|
||||
foreach($actions as $id => $action) {
|
||||
foreach($default_fields as $field => $value) {
|
||||
if (!isset($action[$field])) {
|
||||
$actions[$id][$field] = $value;
|
||||
}
|
||||
}
|
||||
$done = $this->AdminSetting->getSetting($id);
|
||||
$actions[$id]['done'] = ($done == '1');
|
||||
}
|
||||
$this->set('actions', $actions);
|
||||
$this->set('updateLocked', $this->Server->isUpdateLocked());
|
||||
}
|
||||
|
||||
public function updateProgress()
|
||||
{
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
throw new MethodNotAllowedException('You are not authorised to do that.');
|
||||
}
|
||||
$update_progress = $this->Server->getUpdateProgress();
|
||||
$current_index = $update_progress['current'];
|
||||
$current_command = !isset($update_progress['commands'][$current_index]) ? '' : $update_progress['commands'][$current_index];
|
||||
$lookup_string = preg_replace('/\s{2,}/', '', substr($current_command, 0, -1));
|
||||
$sql_info = $this->Server->query("SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;");
|
||||
if (empty($sql_info)) {
|
||||
$update_progress['process_list'] = array();
|
||||
} else {
|
||||
// retreive current update process
|
||||
foreach($sql_info as $row) {
|
||||
if (preg_replace('/\s{2,}/', '', $row['PROCESSLIST']['INFO']) == $lookup_string) {
|
||||
$sql_info = $row['PROCESSLIST'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$update_progress['process_list'] = array();
|
||||
$update_progress['process_list']['STATE'] = isset($sql_info['STATE']) ? $sql_info['STATE'] : '';
|
||||
$update_progress['process_list']['PROGRESS'] = isset($sql_info['PROGRESS']) ? $sql_info['PROGRESS'] : 0;
|
||||
$update_progress['process_list']['STAGE'] = isset($sql_info['STAGE']) ? $sql_info['STAGE'] : 0;
|
||||
$update_progress['process_list']['MAX_STAGE'] = isset($sql_info['MAX_STAGE']) ? $sql_info['MAX_STAGE'] : 0;
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
return $this->RestResponse->viewData(h($update_progress), $this->response->type());
|
||||
} else {
|
||||
$this->set('updateProgress', $update_progress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getSubmoduleQuickUpdateForm($submodule_path=false) {
|
||||
$this->set('submodule', base64_decode($submodule_path));
|
||||
$this->render('ajax/submodule_quick_update_form');
|
||||
|
|
|
@ -78,6 +78,21 @@ class AppModel extends Model
|
|||
33 => false, 34 => false
|
||||
);
|
||||
|
||||
public $advanced_updates_description = array(
|
||||
);
|
||||
public $actions_description = array(
|
||||
'verifyGnuPGkeys' => array(
|
||||
'title' => 'Verify GnuPG keys',
|
||||
'description' => "Run a full validation of all GnuPG keys within this instance's userbase. The script will try to identify possible issues with each key and report back on the results.",
|
||||
'url' => '/users/verifyGPG/'
|
||||
),
|
||||
'databaseCleanupScripts' => array(
|
||||
'title' => 'Database Cleanup Scripts',
|
||||
'description' => 'If you run into an issue with an infinite upgrade loop (when upgrading from version ~2.4.50) that ends up filling your database with upgrade script log messages, run the following script.',
|
||||
'url' => '/logs/pruneUpdateLogs/'
|
||||
)
|
||||
);
|
||||
|
||||
public function afterSave($created, $options = array())
|
||||
{
|
||||
if ($created) {
|
||||
|
@ -209,8 +224,46 @@ class AppModel extends Model
|
|||
}
|
||||
|
||||
// SQL scripts for updates
|
||||
public function updateDatabase($command)
|
||||
public function updateDatabase($command, $useWorker=true)
|
||||
{
|
||||
// Exit if updates are locked
|
||||
if ($this->isUpdateLocked()) {
|
||||
return false;
|
||||
}
|
||||
$this->__resetUpdateProgress();
|
||||
// restart this function by a worker
|
||||
if ($useWorker && Configure::read('MISP.background_jobs')) {
|
||||
$job = ClassRegistry::init('Job');
|
||||
$job->create();
|
||||
$data = array(
|
||||
'worker' => 'prio',
|
||||
'job_type' => 'update_app',
|
||||
'job_input' => 'command: ' . $command,
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org_id' => '',
|
||||
'org' => '',
|
||||
'message' => 'Updating.',
|
||||
);
|
||||
$job->save($data);
|
||||
$jobId = $job->id;
|
||||
$process_id = CakeResque::enqueue(
|
||||
'prio',
|
||||
'AdminShell',
|
||||
array('updateApp', $command, $jobId),
|
||||
true
|
||||
);
|
||||
$job->saveField('process_id', $process_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
$liveOff = false;
|
||||
$exitOnError = false;
|
||||
if (isset($advanced_updates_description[$command])) {
|
||||
$liveOff = isset($advanced_updates_description[$command]['liveOff']) ? $advanced_updates_description[$command]['liveOff'] : $liveOff;
|
||||
$exitOnError = isset($advanced_updates_description[$command]['exitOnError']) ? $advanced_updates_description[$command]['exitOnError'] : $exitOnError;
|
||||
}
|
||||
|
||||
$dataSourceConfig = ConnectionManager::getDataSource('default')->config;
|
||||
$dataSource = $dataSourceConfig['datasource'];
|
||||
$sqlArray = array();
|
||||
|
@ -1150,52 +1203,123 @@ class AppModel extends Model
|
|||
return false;
|
||||
break;
|
||||
}
|
||||
foreach ($sqlArray as $sql) {
|
||||
|
||||
$now = new DateTime();
|
||||
$this->__changeLockState(time());
|
||||
// switch MISP instance live to false
|
||||
if ($liveOff) {
|
||||
$this->Server = Classregistry::init('Server');
|
||||
$liveSetting = 'MISP.live';
|
||||
$this->Server->serverSettingsSaveValue($liveSetting, false);
|
||||
}
|
||||
$sql_update_count = count($sqlArray);
|
||||
$index_update_count = count($indexArray);
|
||||
$total_update_count = $sql_update_count + $index_update_count;
|
||||
$this->__setUpdateProgress(0, $total_update_count);
|
||||
$str_index_array = array();
|
||||
foreach($indexArray as $toIndex) {
|
||||
$str_index_array[] = __('Indexing ') . implode($toIndex, '->');
|
||||
}
|
||||
$this->__setUpdateCmdMessages(array_merge($sqlArray, $str_index_array));
|
||||
$flag_stop = false;
|
||||
$error_count = 0;
|
||||
|
||||
// execute test before update. Exit if it fails
|
||||
if (isset($this->advanced_updates_description[$command]['preUpdate'])) {
|
||||
$function_name = $this->advanced_updates_description[$command]['preUpdate'];
|
||||
try {
|
||||
$this->query($sql);
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'update_database',
|
||||
'user_id' => 0,
|
||||
'title' => 'Successfuly executed the SQL query for ' . $command,
|
||||
'change' => 'The executed SQL query was: ' . $sql
|
||||
));
|
||||
$this->{$function_name}();
|
||||
} catch (Exception $e) {
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'update_database',
|
||||
'user_id' => 0,
|
||||
'title' => 'Issues executing the SQL query for ' . $command,
|
||||
'change' => 'The executed SQL query was: ' . $sql . PHP_EOL . ' The returned error is: ' . $e->getMessage()
|
||||
));
|
||||
$this->__setPreUpdateTestState(false);
|
||||
$this->__setUpdateProgress(0, false);
|
||||
$this->__setUpdateResMessages(0, __('Issues executing the pre-update test `') . $function_name . __('`. The returned error is: ') . PHP_EOL . $e->getMessage());
|
||||
$this->__setUpdateError(0);
|
||||
$error_count++;
|
||||
$exitOnError = true;
|
||||
$flag_stop = true;
|
||||
}
|
||||
}
|
||||
if (!empty($indexArray)) {
|
||||
if ($clean) {
|
||||
$this->cleanCacheFiles();
|
||||
}
|
||||
foreach ($indexArray as $iA) {
|
||||
if (isset($iA[2])) {
|
||||
$this->__addIndex($iA[0], $iA[1], $iA[2]);
|
||||
} else {
|
||||
$this->__addIndex($iA[0], $iA[1]);
|
||||
|
||||
if (!$flag_stop) {
|
||||
$this->__setPreUpdateTestState(true);
|
||||
foreach ($sqlArray as $i => $sql) {
|
||||
try {
|
||||
$this->__setUpdateProgress($i, false);
|
||||
$this->query($sql);
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'update_database',
|
||||
'user_id' => 0,
|
||||
'title' => __('Successfuly executed the SQL query for ') . $command,
|
||||
'change' => __('The executed SQL query was: ') . $sql
|
||||
));
|
||||
$this->__setUpdateResMessages($i, __('Successfuly executed the SQL query for ') . $command);
|
||||
} catch (Exception $e) {
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'update_database',
|
||||
'user_id' => 0,
|
||||
'title' => __('Issues executing the SQL query for ') . $command,
|
||||
'change' => __('The executed SQL query was: ') . $sql . PHP_EOL . __(' The returned error is: ') . $e->getMessage()
|
||||
));
|
||||
$this->__setUpdateResMessages($i, __('Issues executing the SQL query for ') . $command . __('. The returned error is: ') . PHP_EOL . $e->getMessage());
|
||||
$this->__setUpdateError($i);
|
||||
$error_count++;
|
||||
if ($exitOnError) {
|
||||
$flag_stop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$flag_stop) {
|
||||
if (!empty($indexArray)) {
|
||||
if ($clean) {
|
||||
$this->cleanCacheFiles();
|
||||
}
|
||||
foreach ($indexArray as $i => $iA) {
|
||||
$this->__setUpdateProgress(count($sqlArray)+$i, false);
|
||||
if (isset($iA[2])) {
|
||||
$this->__addIndex($iA[0], $iA[1], $iA[2]);
|
||||
} else {
|
||||
$this->__addIndex($iA[0], $iA[1]);
|
||||
}
|
||||
$this->__setUpdateResMessages(count($sqlArray)+$i, __('Successfuly indexed ') . implode($iA, '->'));
|
||||
}
|
||||
}
|
||||
$this->__setUpdateProgress(count($sqlArray)+count($indexArray), false);
|
||||
}
|
||||
if ($clean) {
|
||||
$this->cleanCacheFiles();
|
||||
}
|
||||
if ($liveOff) {
|
||||
$liveSetting = 'MISP.live';
|
||||
$this->Server->serverSettingsSaveValue($liveSetting, true);
|
||||
}
|
||||
if (!$flag_stop && $error_count == 0) {
|
||||
$this->__postUpdate($command);
|
||||
}
|
||||
$this->__changeLockState(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// check whether the adminSetting should be updated after the update
|
||||
private function __postUpdate($command) {
|
||||
if (isset($this->advanced_updates_description[$command]['record'])) {
|
||||
if($this->advanced_updates_description[$command]['record']) {
|
||||
$this->AdminSetting->changeSetting($command, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function __dropIndex($table, $field)
|
||||
{
|
||||
$dataSourceConfig = ConnectionManager::getDataSource('default')->config;
|
||||
|
@ -1390,6 +1514,126 @@ class AppModel extends Model
|
|||
if ($requiresLogout) {
|
||||
$this->updateDatabase('destroyAllSessions');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function __setUpdateProgress($current, $total=false)
|
||||
{
|
||||
$updateProgress = $this->getUpdateProgress();
|
||||
$updateProgress['current'] = $current;
|
||||
if ($total !== false) {
|
||||
$updateProgress['total'] = $total;
|
||||
} else {
|
||||
$now = new DateTime();
|
||||
$updateProgress['time']['started'][$current] = $now->format('Y-m-d H:i:s');
|
||||
}
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
private function __setPreUpdateTestState($state)
|
||||
{
|
||||
$updateProgress = $this->getUpdateProgress();
|
||||
$updateProgress['preTestSuccess'] = $state;
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
private function __setUpdateError($index)
|
||||
{
|
||||
$updateProgress = $this->getUpdateProgress();
|
||||
$updateProgress['failed_num'][] = $index;
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
private function __resetUpdateProgress()
|
||||
{
|
||||
$updateProgress = array(
|
||||
'commands' => array(),
|
||||
'results' => array(),
|
||||
'time' => array('started' => array(), 'elapsed' => array()),
|
||||
'current' => '',
|
||||
'total' => '',
|
||||
'failed_num' => array()
|
||||
);
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
private function __setUpdateCmdMessages($messages)
|
||||
{
|
||||
$updateProgress = $this->getUpdateProgress();
|
||||
$updateProgress['commands'] = $messages;
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
private function __setUpdateResMessages($index, $message)
|
||||
{
|
||||
$updateProgress = $this->getUpdateProgress();
|
||||
$updateProgress['results'][$index] = $message;
|
||||
$temp = new DateTime();
|
||||
$diff = $temp->diff(new DateTime($updateProgress['time']['started'][$index]));
|
||||
$updateProgress['time']['elapsed'][$index] = $diff->format('%H:%I:%S');
|
||||
$this->__saveUpdateProgress($updateProgress);
|
||||
}
|
||||
|
||||
public function getUpdateProgress()
|
||||
{
|
||||
if (!isset($this->AdminSetting)) {
|
||||
$this->AdminSetting = ClassRegistry::init('AdminSetting');
|
||||
}
|
||||
$updateProgress = $this->AdminSetting->getSetting('update_progress');
|
||||
if ($updateProgress !== false) {
|
||||
$updateProgress = json_decode($updateProgress, true);
|
||||
} else {
|
||||
$this->__resetUpdateProgress();
|
||||
$updateProgress = $this->AdminSetting->getSetting('update_progress');
|
||||
$updateProgress = json_decode($updateProgress, true);
|
||||
}
|
||||
foreach($updateProgress as $setting => $value) {
|
||||
if (!is_array($value)) {
|
||||
$value = $value !== false && $value !== '' ? intval($value) : 0;
|
||||
}
|
||||
$updateProgress[$setting] = $value;
|
||||
}
|
||||
return $updateProgress;
|
||||
}
|
||||
|
||||
private function __saveUpdateProgress($updateProgress)
|
||||
{
|
||||
$data = json_encode($updateProgress);
|
||||
$this->AdminSetting->changeSetting('update_progress', $data);
|
||||
}
|
||||
|
||||
private function __changeLockState($locked)
|
||||
{
|
||||
$this->AdminSetting->changeSetting('update_locked', $locked);
|
||||
}
|
||||
|
||||
private function getUpdateLockState()
|
||||
{
|
||||
if (!isset($this->AdminSetting)) {
|
||||
$this->AdminSetting = ClassRegistry::init('AdminSetting');
|
||||
}
|
||||
$locked = $this->AdminSetting->getSetting('update_locked');
|
||||
return is_null($locked) ? false : $locked;
|
||||
}
|
||||
|
||||
public function isUpdateLocked()
|
||||
{
|
||||
$lockState = $this->getUpdateLockState();
|
||||
if ($lockState !== false && $lockState !== '') {
|
||||
// if lock is old, still allows the update
|
||||
// This can be useful if the update process crashes
|
||||
$diffSec = time() - intval($lockState);
|
||||
if (Configure::read('MISP.updateTimeThreshold')) {
|
||||
$updateWaitThreshold = intval(Configure::read('MISP.updateTimeThreshold'));
|
||||
} else {
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$updateWaitThreshold = intval($this->Server->serverSettings['MISP']['updateTimeThreshold']['value']);
|
||||
}
|
||||
if ($diffSec < $updateWaitThreshold) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __queueCleanDB()
|
||||
|
|
|
@ -915,7 +915,15 @@ class Server extends AppModel
|
|||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => true
|
||||
)
|
||||
),
|
||||
'updateTimeThreshold' => array(
|
||||
'level' => 1,
|
||||
'description' => __('Sets the minimum time before being able to re-trigger an update if the previous one failed. (safe guard to avoid starting the same update multiple time)'),
|
||||
'value' => '7200',
|
||||
'test' => 'testForNumeric',
|
||||
'type' => 'numeric',
|
||||
'null' => true
|
||||
)
|
||||
),
|
||||
'GnuPG' => array(
|
||||
'branch' => 1,
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
$message = str_replace('$flashErrorMessage', '<span class="useCursorPointer underline bold" onClick="flashErrorPopover();">here</span>', $message);
|
||||
}
|
||||
echo $message;
|
||||
if (isset($params['url'])) {
|
||||
if (isset($params['urlName'])) {
|
||||
echo '<a href="' . h($params['url']) . '">' . h($params['urlName']) . '</a>';
|
||||
} else {
|
||||
echo '<a href="' . h($params['url']) . '">' . h($params['url']) . '</a>';
|
||||
}
|
||||
}
|
||||
if ($this->Session->read('flashErrorMessage')) {
|
||||
echo sprintf('<div class="hidden" id="flashErrorMessage">%s</div>', $this->element('flashErrorMessage', array('message' => $this->Session->read('flashErrorMessage'))));
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
</span><br />
|
||||
<pre class="hidden green bold" id="gitResult"></pre>
|
||||
<button title="<?php echo __('Pull the latest MISP version from github');?>" class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "updateMISP();"><?php echo __('Update MISP');?></button>
|
||||
<a title="<?php echo __('Click the following button to go to the update progress page. This page lists all updates that are currently queued and executed.'); ?>" class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" href="<?php echo $baseurl; ?>/servers/updateProgress/"><?php echo __('Update Progress');?></a>
|
||||
</div>
|
||||
<h3><?php echo __('Submodules version');?>
|
||||
<it id="refreshSubmoduleStatus" class="fas fa-sync useCursorPointer" style="font-size: small; margin-left: 5px;" title="<?php echo __('Refresh submodules version.'); ?>"></it>
|
||||
|
@ -361,12 +362,9 @@
|
|||
</div><br />
|
||||
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="<?php echo __('Check for orphaned attribute');?>" title="<?php echo __('Check for orphaned attributes');?>" style="padding-top:1px;padding-bottom:1px;" onClick="checkOrphanedAttributes();"><?php echo __('Check for orphaned attributes');?></span><br /><br />
|
||||
<?php echo $this->Form->postButton(__('Remove orphaned attributes'), $baseurl . '/attributes/pruneOrphanedAttributes', $options = array('class' => 'btn btn-primary', 'style' => 'padding-top:1px;padding-bottom:1px;')); ?>
|
||||
<h3><?php echo __('Verify GnuPG keys');?></h3>
|
||||
<p><?php echo __('Run a full validation of all GnuPG keys within this instance\'s userbase. The script will try to identify possible issues with each key and report back on the results.');?></p>
|
||||
<span class="btn btn-inverse" onClick="location.href='<?php echo $baseurl;?>/users/verifyGPG';"><?php echo __('Verify GnuPG keys');?></span> (<?php echo __('Check whether every user\'s GnuPG key is usable');?>)</li>
|
||||
<h3><?php echo __('Database cleanup scripts');?></h3>
|
||||
<p><?php echo __('If you run into an issue with an infinite upgrade loop (when upgrading from version ~2.4.50) that ends up filling your database with upgrade script log messages, run the following script.');?></p>
|
||||
<?php echo $this->Form->postButton(__('Prune upgrade logs'), $baseurl . '/logs/pruneUpdateLogs', $options = array('class' => 'btn btn-primary', 'style' => 'padding-top:1px;padding-bottom:1px;')); ?>
|
||||
<h3><?php echo __('Administrator On-demand Action');?></h3>
|
||||
<p><?php echo __('Click the following button to go to the Administrator On-demand Action page.');?></p>
|
||||
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick="location.href = '<?php echo $baseurl; ?>/servers/ondemandAction/';"><?php echo __('Administrator On-demand Action');?></span>
|
||||
<h3><?php echo __('Legacy Administrative Tools');?></h3>
|
||||
<p><?php echo __('Click the following button to go to the legacy administrative tools page. There should in general be no need to do this unless you are upgrading a very old MISP instance (<2.4), all updates are done automatically with more current versions.');?></p>
|
||||
<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick="location.href = '<?php echo $baseurl; ?>/pages/display/administration';"><?php echo __('Legacy Administrative Tools');?></span>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
if (!$isSiteAdmin) exit();
|
||||
$disabledBtnText = $updateLocked ? 'title="' . __('An action is already in progress...') . '" disabled' : 'title=' . __('Action');
|
||||
?>
|
||||
|
||||
<div class="index">
|
||||
<h2><?php echo __('Administrator On-demand Action'); ?></h2>
|
||||
|
||||
<?php if ($updateLocked): ?>
|
||||
<div class='alert alert-danger'>
|
||||
<?php echo __('An action is already in progress. Starting new actions is not possible until completion of the current action process.'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<a id="btnShowProgress" class="btn btn-inverse" href="<?php echo $baseurl; ?>/servers/updateProgress/"><?php echo __('Show Update Progress Page'); ?></a>
|
||||
</div>
|
||||
|
||||
<?php $i = 0; ?>
|
||||
<?php foreach($actions as $id => $action): ?>
|
||||
<div class="headerUpdateBlock">
|
||||
<h4><?php echo ($i+1) . '. ' . h($action['title']); ?></h4>
|
||||
</div>
|
||||
<div class="bodyUpdateBlock">
|
||||
<h5><?php echo h($action['description']); ?></h5>
|
||||
|
||||
<?php if (!$action['done']): ?>
|
||||
|
||||
<?php if ($action['requirements'] !== ''): ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="icon-warning-sign"></i> <?php echo h($action['requirements']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($action['recommendBackup']): ?>
|
||||
<div class="alert alert-block">
|
||||
<i class="icon-warning-sign"></i> <?php echo __('Running this script may take a very long time depending of the size of your database. It is adviced that you <b>back your database up</b> before running it.'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($action['liveOff']): ?>
|
||||
<div class="alert alert-info">
|
||||
<i class="icon-question-sign"></i> <?php echo __('Running this script will make this instance unusable for all users (not site-admin) during the time of upgrade.'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$url_param = $action['liveOff'] ? '1' : '';
|
||||
$url_param .= $action['exitOnError'] ? '/1' : '';
|
||||
echo $this->Form->create(false, array( 'url' => $baseurl . $action['url'] . $url_param ));
|
||||
?>
|
||||
|
||||
<button class="btn btn-warning <?php echo isset($action['redirectToUpdateProgress']) && $action['redirectToUpdateProgress'] ? 'submitButton' : 'submitButtonToUpdateProgress'; ?>" <?php echo $disabledBtnText; ?> role="button" tabindex="0" aria-label="<?php echo __('Submit'); ?>"><?php echo __('Action: ') . h($action['title']); ?></button>
|
||||
|
||||
<?php
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fa fa-check-square"></i> <?php echo __('This action has been done and cannot be run again.'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $i++; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->element('side_menu', array('menuList' => 'admin', 'menuItem' => 'adminTools'));
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('.submitButtonToUpdateProgress').click(function() {
|
||||
var form = $(this).closest("form");
|
||||
$.ajax({
|
||||
data: form.serialize(),
|
||||
cache: false,
|
||||
timeout: 100,
|
||||
complete: function (data, textStatus) {
|
||||
window.location.href = $('#btnShowProgress').prop('href');
|
||||
},
|
||||
type:"post",
|
||||
url: form.prop('action')
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
if (!$isSiteAdmin) exit();
|
||||
if ($updateProgress['total'] !== 0 ) {
|
||||
$percentageFail = floor(count($updateProgress['failed_num']) / $updateProgress['total']*100);
|
||||
$percentage = floor(($updateProgress['current']) / $updateProgress['total']*100);
|
||||
} else {
|
||||
$percentage = 100;
|
||||
$percentageFail = 0;
|
||||
}
|
||||
|
||||
if (isset($updateProgress['preTestSuccess']) && $updateProgress['preTestSuccess'] === false) {
|
||||
$percentage = 0;
|
||||
$percentageFail = 100;
|
||||
}
|
||||
?>
|
||||
<div style="width: 50%;margin: 0 auto;">
|
||||
<?php if (count($updateProgress['commands']) > 0): ?>
|
||||
<h2><?php echo(__('Database Update progress'));?></h2>
|
||||
<div class="" style="max-width: 1000px;">
|
||||
|
||||
<div>
|
||||
<h5 style='display: inline-block'>Pre update test status:</h5>
|
||||
<?php
|
||||
$icon = isset($updateProgress['preTestSuccess']) ? ($updateProgress['preTestSuccess'] ? 'fa-check' : 'fa-times') : 'fa-question-circle ';
|
||||
?>
|
||||
<i class='fa <?php echo($icon); ?>' style="font-size: x-large"></i>
|
||||
</div>
|
||||
|
||||
<div class="progress progress-striped" style="max-width: 1000px;">
|
||||
<div id="pb-progress" class="bar" style="font-weight: bold; width: <?php echo h($percentage);?>%;"><?php echo h($percentage);?>%</div>
|
||||
<div id="pb-fail" class="bar" style="width: <?php echo h($percentageFail);?>%; background-color: #ee5f5b;"></div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-stripped updateProgressTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Update command</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($updateProgress['commands'] as $i => $cmd):
|
||||
if (isset($updateProgress['results'][$i])) {
|
||||
$res = $updateProgress['results'][$i];
|
||||
} else {
|
||||
$res = false;
|
||||
}
|
||||
$rowDone = $i < $updateProgress['current'];
|
||||
$rowCurrent = $i === $updateProgress['current'];
|
||||
$rowFail = in_array($i, $updateProgress['failed_num']);
|
||||
$rowClass = '';
|
||||
$rowIcon = '<i id="icon-' . $i . '" class="fa"></i>';
|
||||
if ($rowDone) {
|
||||
$rowClass = 'class="alert alert-success"';
|
||||
$rowIcon = '<i id="icon-' . $i . '" class="fa fa-check-circle-o"></i>';
|
||||
}
|
||||
if ($rowCurrent && !$rowFail) {
|
||||
$rowClass = 'class="alert alert-info"';
|
||||
$rowIcon = '<i id="icon-' . $i . '" class="fa fa-cogs"></i>';
|
||||
} else if ($rowFail) {
|
||||
$rowClass = 'class="alert alert-danger"';
|
||||
$rowIcon = '<i id="icon-' . $i . '" class="fa fa-times-circle-o"></i>';
|
||||
}
|
||||
|
||||
if (isset($updateProgress['time']['started'][$i])) {
|
||||
$datetimeStart = $updateProgress['time']['started'][$i];
|
||||
if (isset($updateProgress['time']['elapsed'][$i])) {
|
||||
$updateDuration = $updateProgress['time']['elapsed'][$i];
|
||||
} else { // compute elapsed based on started
|
||||
$temp = new DateTime();
|
||||
$diff = $temp->diff(new DateTime($datetimeStart));
|
||||
$updateDuration = $diff->format('%H:%I:%S');
|
||||
}
|
||||
} else {
|
||||
$datetimeStart = '';
|
||||
$updateDuration = '';
|
||||
}
|
||||
?>
|
||||
<tr id="row-<?php echo $i; ?>" <?php echo $rowClass; ?> >
|
||||
<td><?php echo $rowIcon; ?></td>
|
||||
<td>
|
||||
<div>
|
||||
<a style="cursor: pointer; maring-bottom: 2px;" onclick="toggleVisiblity(<?php echo $i;?>)">
|
||||
<span class="foldable fa fa-terminal"></span>
|
||||
<?php echo __('Update ') . ($i+1); ?>
|
||||
<span class="inline-term"><?php echo h(substr($cmd, 0, 60)) . (strlen($cmd) > 60 ? '[...]' : '' );?></span>
|
||||
<span class="label">
|
||||
<?php echo __('Started @ '); ?>
|
||||
<span id="startedTime-<?php echo $i; ?>"><?php echo h($datetimeStart); ?></span>
|
||||
</span>
|
||||
<span class="label">
|
||||
<?php echo __('Elapsed Time @ '); ?>
|
||||
<span id="elapsedTime-<?php echo $i; ?>"><?php echo h($updateDuration); ?></span>
|
||||
</span>
|
||||
|
||||
</a>
|
||||
<div data-terminalid="<?php echo $i;?>" style="display: none; margin-top: 5px;">
|
||||
<div id="termcmd-<?php echo $i;?>" class="div-terminal">
|
||||
<?php
|
||||
$temp = preg_replace('/^\n*\s+/', '', $cmd);
|
||||
$temp = preg_split('/\s{4,}/m', $temp);
|
||||
foreach ($temp as $j => $line) {
|
||||
$pad = $j > 0 ? '30' : '0';
|
||||
if ($line !== '') {
|
||||
echo '<span style="margin-left: ' . $pad . 'px;">' . h($line) . '</span>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div>
|
||||
<span class="fa fa-level-up terminal-res-icon"></span>
|
||||
<div id="termres-<?php echo $i;?>" class="div-terminal terminal-res">
|
||||
<?php
|
||||
if ($res !== false) {
|
||||
$temp = preg_replace('/^\n*\s+/', '', $res);
|
||||
$temp = preg_split('/\s{2,}/m', $temp);
|
||||
foreach ($temp as $j => $line) {
|
||||
$pad = $j > 0 ? '30' : '0';
|
||||
if ($line !== '') {
|
||||
echo '<span style="margin-left: ' . $pad . 'px;">' . h($line) . '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="single-update-progress-<?php echo $i;?>" class="single-update-progress hidden">
|
||||
<div class="small-pb-in-td">
|
||||
<div id="single-update-pb-<?php echo $i;?>" style="height: 100%; background: #149bdf; transition: width 0.6s ease;"></div>
|
||||
</div>
|
||||
|
||||
<div id="small-state-text-<?php echo $i;?>" class="small-state-text-in-td badge" class="badge">Filling schema table</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<h2><?php echo __('No update in progress'); ?></h2>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
setInterval(function() { location.reload(); }, 1000);
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<script>
|
||||
var updateProgress = <?php echo json_encode($updateProgress); ?>;
|
||||
var urlGetProgress = "<?php echo $baseurl; ?>/servers/updateProgress";
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('genericElements/assetLoader', array(
|
||||
'css' => array('update_progress'),
|
||||
'js' => array('update_progress')
|
||||
));
|
||||
?>
|
||||
</div>
|
|
@ -0,0 +1,76 @@
|
|||
.headerUpdateBlock {
|
||||
border: #ccc solid 1px;
|
||||
border-bottom: 1px solid transparent;
|
||||
background: #e6e6e6;
|
||||
padding: 0px 6px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
.bodyUpdateBlock {
|
||||
border: #ccc solid 1px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
background: #fbfbfb;
|
||||
padding: 6px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.div-terminal {
|
||||
background-color: #303030;
|
||||
color: white;
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.div-terminal > span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.terminal-res {
|
||||
margin-top: 5px;
|
||||
margin-left: 25px;
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.terminal-res-icon {
|
||||
position: absolute;
|
||||
transform: rotate(90deg);
|
||||
font-size: large;
|
||||
margin-right: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
table.updateProgressTable > tbody > tr > td:first-child {
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.updateProgressTable .small-pb-in-td {
|
||||
width: calc(100% + 16px);
|
||||
height: 4px;
|
||||
position: relative;
|
||||
left: -8px;
|
||||
top: 26px;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
table.updateProgressTable .small-state-text-in-td {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
|
||||
}
|
||||
|
||||
.back-and-forth-animation {
|
||||
position: relative;
|
||||
animation: backandforthAnim 2.0s infinite;
|
||||
}
|
||||
|
||||
@keyframes backandforthAnim {
|
||||
0% {left: 0;}
|
||||
50% {left: calc(95%);}
|
||||
100% {left: 0;}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
function toggleVisiblity(termId, auto, show) {
|
||||
var term = $('div[data-terminalid='+termId+']')
|
||||
if (auto === true) {
|
||||
if (term.data('manual') !== true) { // show if manual is not set
|
||||
if (show === true) {
|
||||
term.show();
|
||||
} else if (show === false) {
|
||||
term.hide();
|
||||
} else {
|
||||
term.toggle();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
term.data('manual', true);
|
||||
if (show === true) {
|
||||
term.show();
|
||||
} else if (show === false) {
|
||||
term.hide();
|
||||
} else {
|
||||
term.toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var pooler;
|
||||
var poolerInterval = 3000;
|
||||
$(document).ready(function() {
|
||||
pooler = setInterval(function() { update_state(); }, poolerInterval);
|
||||
});
|
||||
|
||||
|
||||
function update_state() {
|
||||
$.getJSON(urlGetProgress, function(data) {
|
||||
var total = parseInt(data['total']);
|
||||
var current = parseInt(data['current']);
|
||||
var failArray = data['failed_num'];
|
||||
for (var i=0; i<total; i++) {
|
||||
var term = $('div[data-terminalid='+i+']')
|
||||
toggleVisiblity(i, true, false);
|
||||
if (i < current) {
|
||||
if (failArray.indexOf(String(i)) != -1) {
|
||||
update_row_state(i, 2);
|
||||
} else {
|
||||
update_row_state(i, 0);
|
||||
}
|
||||
} else if (i == current) {
|
||||
if (failArray.indexOf(String(i)) != -1) {
|
||||
update_row_state(i, 2);
|
||||
toggleVisiblity(i, true, true);
|
||||
} else {
|
||||
update_row_state(i, 1);
|
||||
toggleVisiblity(i-1, true, true);
|
||||
}
|
||||
update_single_update_progress(i, data);
|
||||
} else {
|
||||
update_row_state(i, 3);
|
||||
}
|
||||
}
|
||||
update_messages(data);
|
||||
if (total > 0) {
|
||||
var percFail = Math.round(failArray.length/total*100);
|
||||
var perc = Math.round(current/total*100);
|
||||
update_pb(perc, percFail);
|
||||
}
|
||||
|
||||
if ((current+1) >= total || failArray.indexOf(current) != -1) {
|
||||
clearInterval(pooler);
|
||||
$('.single-update-progress').hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function update_messages(messages) {
|
||||
if (messages.commands === undefined) {
|
||||
return;
|
||||
}
|
||||
messages.commands.forEach(function(msg, i) {
|
||||
var div = $('#termcmd-'+i);
|
||||
create_spans_from_message(div, msg);
|
||||
});
|
||||
messages.results.forEach(function(msg, i) {
|
||||
var div = $('#termres-'+i);
|
||||
div.css('display', '');
|
||||
create_spans_from_message(div, msg);
|
||||
});
|
||||
messages.time.started.forEach(function(startedText, i) {
|
||||
var elapsedText = messages.time.elapsed[i];
|
||||
if (elapsedText === undefined) {
|
||||
var diff = new Date((new Date()).getTime() - (new Date(startedText)).getTime());
|
||||
elapsedText = pad(diff.getUTCHours(), 2)
|
||||
+ ':' + pad(diff.getUTCMinutes(), 2)
|
||||
+ ':' + pad(diff.getUTCSeconds(), 2);
|
||||
}
|
||||
update_times(i, startedText, elapsedText)
|
||||
});
|
||||
}
|
||||
|
||||
function create_spans_from_message(toAppendto, msg) {
|
||||
toAppendto.empty();
|
||||
// create span for each line of text
|
||||
msg = msg.replace(/^\n*\s+/, '');
|
||||
var lines = msg.split(/\s{2,}/m)
|
||||
lines.forEach(function(line, j) {
|
||||
var pad = j > 0 ? '30' : '0';
|
||||
if (line !== '') {
|
||||
var span = $('<span style="margin-left: ' + pad + 'px;">' + line + '</span>');
|
||||
toAppendto.append(span);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function update_row_state(i, state) {
|
||||
var icon = $('#icon-'+i);
|
||||
var row = $('#row-'+i);
|
||||
switch(state) {
|
||||
case 0: // success
|
||||
row.removeClass('alert-danger alert-info');
|
||||
row.addClass('alert-success');
|
||||
icon.removeClass('fa-times-circle-o fa-cogs');
|
||||
icon.addClass('fa-check-circle-o');
|
||||
break;
|
||||
case 1: // current
|
||||
row.removeClass('alert-success alert-danger');
|
||||
row.addClass('alert-info');
|
||||
icon.removeClass('fa-check-circle-o', 'fa-times-circle-o');
|
||||
icon.addClass('fa-cogs');
|
||||
break;
|
||||
case 2: //fail
|
||||
row.removeClass('alert-success alert-info');
|
||||
row.addClass('alert-danger');
|
||||
icon.removeClass('fa-check-circle-o fa-cogs');
|
||||
icon.addClass('fa-times-circle-o');
|
||||
break;
|
||||
case 3: //no state
|
||||
default:
|
||||
row.removeClass('alert-success alert-info alert-danger');
|
||||
icon.removeClass('fa-check-circle-o fa-times-circle-o fa-cogs');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function update_pb(perc, percFail) {
|
||||
var pb = $('#pb-progress');
|
||||
pb.css('width', perc+'%');
|
||||
pb.text(perc+'%');
|
||||
var pbF = $('#pb-fail');
|
||||
pbF.css('width', percFail+'%');
|
||||
}
|
||||
|
||||
function update_times(i, startedText, elapsedText) {
|
||||
var started = $('#startedTime-'+i);
|
||||
var elapsed = $('#elapsedTime-'+i);
|
||||
started.text(startedText);
|
||||
elapsed.text(elapsedText);
|
||||
}
|
||||
|
||||
function update_single_update_progress(i, data) {
|
||||
$('.single-update-progress').hide();
|
||||
var div = $('#single-update-progress-'+i);
|
||||
var pb = div.find('#single-update-pb-'+i);
|
||||
var state = div.find('#small-state-text-'+i);
|
||||
div.show();
|
||||
var perc = parseInt(data['process_list']['PROGRESS']);
|
||||
if (data['process_list']['MAX_STAGE'] == 0) { // if MAX_STAGE == 0, progress could not be determined
|
||||
perc = 5;
|
||||
if (data['failed_num'].indexOf(data['current']) >= 0) { // do not animate if failed
|
||||
state.text('Failed');
|
||||
perc = 0;
|
||||
} else {
|
||||
state.text('Unkown or No state');
|
||||
pb.addClass('back-and-forth-animation');
|
||||
}
|
||||
} else {
|
||||
perc = perc == 0 ? 1 : perc; // for UI, always set min progress to 1
|
||||
pb.removeClass('back-and-forth-animation');
|
||||
state.text(data['process_list']['STATE']);
|
||||
}
|
||||
pb.css('width', perc+'%');
|
||||
}
|
||||
|
||||
function pad(num, size){ return ('000000000' + num).substr(-size); }
|
Loading…
Reference in New Issue