msgid "Audit log:"
msgstr "Audit log:"
+
+msgid "Interpret Bacula errors:"
+msgstr "Interpret Bacula errors:"
msgid "Audit log:"
msgstr "Audit log:"
+
+msgid "Interpret Bacula errors:"
+msgstr "Interpret Bacula errors:"
msgid "Audit log:"
msgstr "Audit log:"
+
+msgid "Interpret Bacula errors:"
+msgstr "Interpret Bacula errors:"
msgid "Audit log:"
msgstr "Audit log:"
+
+msgid "Interpret Bacula errors:"
+msgstr "Interpret Bacula errors:"
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+namespace Baculum\API\Modules;
+
+use Baculum\Common\Modules\Errors\BaculaError as BError;
+
+/**
+ * Parse and handle Bacula errors.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Error
+ * @package Baculum API
+ */
+class BaculaError extends APIModule {
+
+ const DIRECTOR_ERROR_PATTERN = '/^\s*\[(?P<code>D[A-Z]\d{4})\]/';
+ const STORAGE_ERROR_PATTERN = '/^\s*\[(?P<code>S[A-Z]\d{4})\]/';
+ const CLIENT_ERROR_PATTERN = '/^\s*\[(?P<code>F[A-Z]\d{4})\]/';
+ const CONSOLE_ERROR_PATTERN = '/^\s*\[(?P<code>C[A-Z]\d{4})\]/';
+
+ /**
+ * Find first error in output.
+ *
+ * @param array $output bconsole output
+ * @return array with code, error code and message
+ */
+ public function checkForErrors($output) {
+ $code = null;
+ $error = BError::ERROR_NO_ERRORS;
+ $errmsg = BError::MSG_ERROR_NO_ERRORS;
+ for ($i = 0; $i < count($output); $i++) {
+ if (preg_match(self::DIRECTOR_ERROR_PATTERN, $output[$i], $match) === 1) {
+ $code = $match['code'];
+ $error = BError::ERROR_BACULA_DIRECTOR_ERROR;
+ $errmsg = BError::MSG_ERROR_BACULA_DIRECTOR_ERROR;
+ break;
+ } elseif (preg_match(self::STORAGE_ERROR_PATTERN, $output[$i], $match) === 1) {
+ $code = $match['code'];
+ $error = BError::ERROR_BACULA_STORAGE_ERROR;
+ $errmsg = BError::MSG_ERROR_BACULA_STORAGE_ERROR;
+ break;
+ } elseif (preg_match(self::CLIENT_ERROR_PATTERN, $output[$i], $match) === 1) {
+ $code = $match['code'];
+ $error = BError::ERROR_BACULA_CLIENT_ERROR;
+ $errmsg = BError::MSG_ERROR_BACULA_CLIENT_ERROR;
+ break;
+ } elseif (preg_match(self::CONSOLE_ERROR_PATTERN, $output[$i], $match) === 1) {
+ $code = $match['code'];
+ $error = BError::ERROR_BACULA_CONSOLE_ERROR;
+ $errmsg = BError::MSG_ERROR_BACULA_CONSOLE_ERROR;
+ break;
+ }
+ }
+ $result = [
+ 'code' => $code,
+ 'error' => $error,
+ 'errmsg' => $errmsg
+ ];
+ return $result;
+ }
+}
}
}
$output = array_values($output);
- return (object)array('output' => $output, 'exitcode' => (integer)$exitcode);
+ $result = [
+ 'output' => $output,
+ 'exitcode' => (integer)$exitcode
+ ];
+ if (key_exists('interpret_bacula_errors', $this->config) && $this->config['interpret_bacula_errors'] == 1) {
+ $berror = $this->getModule('bacula_error')->checkForErrors($output);
+ if ($berror['error'] != 0) {
+ $result = [
+ 'output' => sprintf(
+ 'Error: %s, BaculaCode: %s, APIError: %s, Output: %s',
+ $berror['errmsg'],
+ $berror['code'],
+ $berror['error'],
+ implode(PHP_EOL, $output)
+ ),
+ 'exitcode' => $berror['error']
+ ];
+ }
+ }
+ return (object)$result;
}
public function bconsoleCommand($director, array $command, $ptype = null, $without_cmd = false) {
<module id="delete" class="Baculum\API\Modules\Delete" />
<module id="list" class="Baculum\API\Modules\BList" />
<module id="time" class="Baculum\API\Modules\TimeManager" />
+ <module id="bacula_error" class="Baculum\API\Modules\BaculaError" />
<!-- changer command modules -->
<module id="changer_command" class="Baculum\API\Modules\ChangerCommand" />
<!-- plugin modules -->
$cfg_data['bconsole']['bin_path'] = $this->BconsolePath->Text;
$cfg_data['bconsole']['cfg_path'] = $this->BconsoleConfigPath->Text;
$cfg_data['bconsole']['use_sudo'] = (integer)($this->UseSudo->Checked === true);
+ $cfg_data['bconsole']['interpret_bacula_errors'] = 1; // it is enabled by default;
$cfg_data['jsontools']['enabled'] = (integer)($this->ConfigYes->Checked === true);
$cfg_data['jsontools']['use_sudo'] = (integer)($this->BJSONUseSudo->Checked === true);
$cfg_data['jsontools']['bconfig_dir'] = $this->BConfigDir->Text;
</table>
</div>
</div>
+ <div class="w3-row w3-section">
+ <div class="w3-col w3-quarter">
+ <com:TLabel
+ ForControl="BconsoleInterpretBaculaErrors"
+ Text="<%[ Interpret Bacula errors: ]%>"
+ />
+ </div>
+ <div class="w3-col w3-threequarter">
+ <com:TCheckBox
+ ID="BconsoleInterpretBaculaErrors"
+ CssClass="w3-check"
+ />
+ </div>
+ </div>
</div>
<div class="w3-row w3-section">
<div class="w3-col w3-center">
$this->BconsolePath->Text = $this->config['bconsole']['bin_path'];
$this->BconsoleConfigPath->Text = $this->config['bconsole']['cfg_path'];
$this->BconsoleUseSudo->Checked = ($this->config['bconsole']['use_sudo'] == 1);
+ if (key_exists('interpret_bacula_errors', $this->config['bconsole'])) {
+ $this->BconsoleInterpretBaculaErrors->Checked = ($this->config['bconsole']['interpret_bacula_errors'] == 1);
+ } else {
+ // Default value if option not specified
+ $this->BconsoleInterpretBaculaErrors->Checked = true;
+ }
}
private function loadConfigSettings() {
'enabled' => ($this->BconsoleEnabled->Checked ? 1 : 0),
'bin_path' => $this->BconsolePath->Text,
'cfg_path' => $this->BconsoleConfigPath->Text,
- 'use_sudo' => ($this->BconsoleUseSudo->Checked ? 1 : 0)
+ 'use_sudo' => ($this->BconsoleUseSudo->Checked ? 1 : 0),
+ 'interpret_bacula_errors' => ($this->BconsoleInterpretBaculaErrors->Checked ? 1 : 0)
];
$this->config['bconsole'] = $cfg;
$this->getModule('api_config')->setConfig($this->config);
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+namespace Baculum\Common\Modules\Errors;
+
+/**
+ * Bacula error class.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Errors
+ * @package Baculum Common
+ */
+class BaculaError extends GenericError {
+
+ const ERROR_BACULA_DIRECTOR_ERROR = 600;
+ const ERROR_BACULA_STORAGE_ERROR = 601;
+ const ERROR_BACULA_CLIENT_ERROR = 602;
+ const ERROR_BACULA_CONSOLE_ERROR = 603;
+
+ const MSG_ERROR_BACULA_DIRECTOR_ERROR = 'Bacula Director error.';
+ const MSG_ERROR_BACULA_STORAGE_ERROR = 'Bacula Storage error.';
+ const MSG_ERROR_BACULA_CLIENT_ERROR = 'Bacula Client error.';
+ const MSG_ERROR_BACULA_CONSOLE_ERROR = 'Bacula Console error.';
+}