const SUDO = 'sudo';
+ /**
+ * Pattern types used to prepare command.
+ */
+ const PTYPE_REG_CMD = 0;
+ const PTYPE_API_CMD = 1;
+ const PTYPE_CONFIRM_YES_CMD = 2;
+
const BCONSOLE_COMMAND_PATTERN = "%s%s -c %s %s 2>&1 <<END_OF_DATA\ngui on\n%s\nquit\nEND_OF_DATA";
+ const BCONSOLE_CONFIRM_YES_COMMAND_PATTERN = "%s%s -c %s %s 2>&1 <<END_OF_DATA\ngui on\n%s\nyes\nquit\nEND_OF_DATA";
+
const BCONSOLE_API_COMMAND_PATTERN = "%s%s -c %s %s 2>&1 <<END_OF_DATA\ngui on\n.api 2 nosignal api_opts=o\n%s\nquit\nEND_OF_DATA";
const BCONSOLE_DIRECTORS_PATTERN = "%s%s -c %s -l 2>&1";
return (object)array('output' => $output, 'exitcode' => (integer)$exitcode);
}
- public function bconsoleCommand($director, array $command, $api = false) {
+ public function bconsoleCommand($director, array $command, $ptype = null) {
if (count($this->config) > 0 && $this->config['enabled'] !== '1') {
throw new BConsoleException(
BconsoleError::MSG_ERROR_BCONSOLE_DISABLED,
}
$base_command = count($command) > 0 ? $command[0] : null;
if($this->isCommandValid($base_command) === true) {
- $result = $this->execCommand($director, $command, $api);
+ $result = $this->execCommand($director, $command, $ptype);
} else {
throw new BConsoleException(
BconsoleError::MSG_ERROR_INVALID_COMMAND,
return $result;
}
- private function execCommand($director, array $command, $api = false) {
+ private function execCommand($director, array $command, $ptype = null) {
$cmd = '';
$result = null;
if(!is_null($director) && $this->isValidDirector($director) === false) {
$dir = is_null($director) ? '': '-D ' . $director;
$sudo = ($this->getUseSudo() === true) ? self::SUDO . ' ' : '';
$bconsole_command = implode(' ', $command);
- $pattern = ($api === true) ? self::BCONSOLE_API_COMMAND_PATTERN : self::BCONSOLE_COMMAND_PATTERN;
+ $pattern = null;
+ switch ($ptype) {
+ case self::PTYPE_API_CMD: $pattern = self::BCONSOLE_API_COMMAND_PATTERN; break;
+ case self::PTYPE_CONFIRM_YES_CMD: $pattern = self::BCONSOLE_CONFIRM_YES_COMMAND_PATTERN; break;
+ default: $pattern = self::BCONSOLE_COMMAND_PATTERN;
+ }
$cmd = sprintf(
$pattern,
$sudo,
* Bacula(R) - The Network Backup Solution
* Baculum - Bacula web interface
*
- * Copyright (C) 2013-2018 Kern Sibbald
+ * Copyright (C) 2013-2019 Kern Sibbald
*
* The main author of Baculum is Marcin Haba.
* The original author of Bacula is Kern Sibbald, with contributions
* Bacula(R) is a registered trademark of Kern Sibbald.
*/
+Prado::using('Application.API.Class.Bconsole');
+
/**
* Component status module.
*/
$result = $this->getModule('bconsole')->bconsoleCommand(
$this->director,
array('status', 'director'),
- true
+ Bconsole::PTYPE_API_CMD
);
if ($result->exitcode === 0) {
$output = $this->getModule('status_dir')->getStatus($result->output);
$result = $this->getModule('bconsole')->bconsoleCommand(
$this->director,
array('.status', $storage, $type),
- true
+ Bconsole::PTYPE_API_CMD
);
if ($result->exitcode === 0) {
$this->output = $this->getModule('status_sd')->getStatus($result->output);
* Bacula(R) is a registered trademark of Kern Sibbald.
*/
+Prado::using('Application.API.Class.Bconsole');
+
class ScheduleStatus extends BaculumAPIServer {
public function get() {
$cmd[] = 'time="' . $this->Request['time'] . '"';
}
- $result = $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd, true);
+ $result = $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd, Bconsole::PTYPE_API_CMD);
if ($result->exitcode === 0) {
array_shift($result->output);
$this->output = $this->formatSchedules($result->output);
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2019 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.
+ */
+
+Prado::using('Application.API.Class.Bconsole');
+
+class VolumeLabel extends BaculumAPIServer {
+
+ public function create($params) {
+ $volume = property_exists($params, 'volume') ? $params->volume : 0;
+ $slot = property_exists($params, 'slot') ? $params->slot : 0;
+ $drive = property_exists($params, 'drive') ? intval($params->drive) : 0;
+ $poolid = property_exists($params, 'poolid') ? intval($params->poolid) : 0;
+ $misc = $this->getModule('misc');
+
+ if (!$misc->isValidName($volume)) {
+ $this->output = VolumeError::ERROR_INVALID_VOLUME;
+ $this->error = VolumeError::MSG_ERROR_INVALID_VOLUME;
+ return;
+ }
+
+ if (!$misc->isValidInteger($slot)) {
+ $this->output = VolumeError::ERROR_INVALID_SLOT;
+ $this->error = VolumeError::MSG_ERROR_INVALID_SLOT;
+ return;
+ }
+
+ $storage = null;
+ if (property_exists($params, 'storageid')) {
+ $storageid = intval($params->storageid);
+ $result = $this->getModule('storage')->getStorageById($storageid);
+ if (is_object($result)) {
+ $storage = $result->name;
+ }
+ } elseif (property_exists($params, 'storage') && $misc->isValidName($params->storage)) {
+ $storage = $params->storage;
+ }
+
+ $pool = null;
+ if (property_exists($params, 'poolid')) {
+ $poolid = intval($params->poolid);
+ $result = $this->getModule('pool')->getPoolById($poolid);
+ if (is_object($result)) {
+ $pool = $result->name;
+ }
+ } elseif (property_exists($params, 'pool') && $misc->isValidName($params->pool)) {
+ $pool = $params->pool;
+ }
+
+ if (!is_null($storage)) {
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ array('.storage')
+ );
+ if ($result->exitcode === 0) {
+ array_shift($result->output);
+ if (!in_array($storage, $result->output)) {
+ $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS;
+ $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS;
+ return;
+ }
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ return;
+ }
+ } else {
+ $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS;
+ $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS;
+ return;
+ }
+
+ if (!is_null($pool)) {
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ array('.pool')
+ );
+ if ($result->exitcode === 0) {
+ array_shift($result->output);
+ if (!in_array($pool, $result->output)) {
+ $this->output = PoolError::MSG_ERROR_POOL_DOES_NOT_EXISTS;
+ $this->error = PoolError::ERROR_POOL_DOES_NOT_EXISTS;
+ return;
+ }
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ return;
+ }
+ } else {
+ $this->output = PoolError::MSG_ERROR_POOL_DOES_NOT_EXISTS;
+ $this->error = PoolError::ERROR_POOL_DOES_NOT_EXISTS;
+ return;
+ }
+
+ $cmd = array(
+ 'label',
+ 'volume="' . $volume . '"',
+ 'storage="' . $storage . '"',
+ 'drive="' . $drive . '"',
+ 'slot="' . $slot . '"',
+ 'pool="' . $pool . '"'
+ );
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ $cmd
+ );
+ if ($result->exitcode === 0) {
+ $this->output = $result->output;
+ $this->error = VolumeError::ERROR_NO_ERRORS;
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ }
+ }
+}
+
+?>
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2019 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.
+ */
+
+Prado::using('Application.API.Class.Bconsole');
+
+class VolumeLabelBarcodes extends BaculumAPIServer {
+
+ public function create($params) {
+ $slots = property_exists($params, 'slots') ? $params->slots : 0;
+ $drive = property_exists($params, 'drive') ? intval($params->drive) : 0;
+ $poolid = property_exists($params, 'poolid') ? intval($params->poolid) : 0;
+ $misc = $this->getModule('misc');
+
+ $storage = null;
+ if (property_exists($params, 'storageid')) {
+ $storageid = intval($params->storageid);
+ $result = $this->getModule('storage')->getStorageById($storageid);
+ if (is_object($result)) {
+ $storage = $result->name;
+ }
+ } elseif (property_exists($params, 'storage') && $misc->isValidName($params->storage)) {
+ $storage = $params->storage;
+ }
+
+ $pool = null;
+ if (property_exists($params, 'poolid')) {
+ $poolid = intval($params->poolid);
+ $result = $this->getModule('pool')->getPoolById($poolid);
+ if (is_object($result)) {
+ $pool = $result->name;
+ }
+ } elseif (property_exists($params, 'pool') && $misc->isValidName($params->pool)) {
+ $pool = $params->pool;
+ }
+
+ if (!is_null($storage)) {
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ array('.storage')
+ );
+ if ($result->exitcode === 0) {
+ array_shift($result->output);
+ if (!in_array($storage, $result->output)) {
+ $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS;
+ $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS;
+ return;
+ }
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ return;
+ }
+ } else {
+ $this->output = StorageError::MSG_ERROR_STORAGE_DOES_NOT_EXISTS;
+ $this->error = StorageError::ERROR_STORAGE_DOES_NOT_EXISTS;
+ return;
+ }
+
+ if (!is_null($pool)) {
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ array('.pool')
+ );
+ if ($result->exitcode === 0) {
+ array_shift($result->output);
+ if (!in_array($pool, $result->output)) {
+ $this->output = PoolError::MSG_ERROR_POOL_DOES_NOT_EXISTS;
+ $this->error = PoolError::ERROR_POOL_DOES_NOT_EXISTS;
+ return;
+ }
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ return;
+ }
+ } else {
+ $this->output = PoolError::MSG_ERROR_POOL_DOES_NOT_EXISTS;
+ $this->error = PoolError::ERROR_POOL_DOES_NOT_EXISTS;
+ return;
+ }
+
+ $cmd = array (
+ 'label',
+ 'barcodes',
+ 'slots="' . $slots . '"',
+ 'storage="' . $storage . '"',
+ 'drive="' . $drive . '"',
+ 'pool="' . $pool . '"'
+ );
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ $cmd,
+ Bconsole::PTYPE_CONFIRM_YES_CMD
+ );
+ if ($result->exitcode === 0) {
+ $this->output = $result->output;
+ $this->error = VolumeError::ERROR_NO_ERRORS;
+ } else {
+ $this->output = $result->output;
+ $this->error = $result->exitcode;
+ }
+ }
+}
+
+?>
<url ServiceParameter="API.VolumePurge" pattern="api/v1/volumes/{id}/purge/" parameters.id="\d+" />
<url ServiceParameter="API.VolumesRequired" pattern="api/v1/volumes/required/{jobid}/{fileid}/" parameters.jobid="\d+" parameters.fileid="\d+" />
<url ServiceParameter="API.JobsOnVolume" pattern="api/v1/volumes/{id}/jobs/" parameters.id="\d+" />
+ <url ServiceParameter="API.VolumeLabel" pattern="api/v1/volumes/label/" />
+ <url ServiceParameter="API.VolumeLabelBarcodes" pattern="api/v1/volumes/label/barcodes/" />
<!-- pools endpoints -->
<url ServiceParameter="API.Pools" pattern="api/v1/pools/" />
<url ServiceParameter="API.Pool" pattern="api/v1/pools/{id}/" parameters.id="\d+" />
class VolumeError extends GenericError {
const ERROR_VOLUME_DOES_NOT_EXISTS = 30;
+ const ERROR_INVALID_VOLUME = 31;
+ const ERROR_INVALID_SLOT = 32;
const MSG_ERROR_VOLUME_DOES_NOT_EXISTS = 'Volume does not exist.';
+ const MSG_ERROR_INVALID_VOLUME = 'Invalid volume.';
+ const MSG_ERROR_INVALID_SLOT = 'Invalid slot.';
}
class PoolError extends GenericError {
return (preg_match('/^\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}$/', $time) === 1);
}
+ public function isValidRange($range) {
+ return (preg_match('/^[\d\-\,]+$/', $range) === 1);
+ }
+
+
/**
* Writing INI-style configuration file.
*