%%
%%

\chapter{Baculum API and Web GUI Tools}
\label{BaculumChapter}

This chapter presents the Bacula Web based interface that has been added to
the Bacula project for version 7.0 and later.

\section{Base Features}

Baculum provides the following base features:

\begin{itemize}
\item Running Bacula jobs (backup, restore, verify...).
\item Baculum API with OAuth2 authorization and HTTP Basic authentication.
\item Baculum Web GUI - modern mobile-friendly web interface.
\item Configuring Bacula on local and remote hosts.
\item Monitoring Bacula service status.
\item Bacula console available via a Web window.
\item Multi-user interface.
\item Support for customized and restricted consoles (Console ACL function).
\item Volume management.
\item User friendly graphs and metrics.
\item Basic storage daemon operations (mount, umount, release, ...).
\item Easy to use configuration and restore wizards.
\item Multiple Director support.
\item Live AJAX based statuses.
\end{itemize}

\section{General Requirements}

Environment for Baculum Web installation should have following components
installed:

\begin{itemize}
\item A Web Server - with mod\_rewrite module loaded.  Baculum Web has been
tested with Apache and Lighttpd web servers.
\item PHP 5.3.4 or higher with following modules installed:
 \begin{itemize}
 \item cURL PHP module.
 \item MB String PHP module.
 \item JSON PHP module.
 \end{itemize}
\end{itemize}

Environment for Baculum API installation should have following components
installed:

\begin{itemize}
\item A Web Server - with mod\_rewrite module loaded.  Baculum has been
tested with Apache and Lighttpd web servers.
\item PHP 5.3.4 or higher with following modules installed:
 \begin{itemize}
 \item PDO PHP support - depending on your catalog database: PDO PostgreSQL
or PDO MySQL. Note, in case using MySQL database there is required to use MySQL
native driver. It is php-mysqlnd for PHP, not php-mysql.
 \item BCMath PHP module.
 \item JSON PHP module.
 \end{itemize}
\item A working Bacula bconsole - configured Bacula text based console
\item Direct access to the Bacula Catalog database (local or remote)
\end{itemize}


With installation from binary packages (deb, rpm) all requirements
will be automatically installed as packages dependencies.

\section{Installation Baculum API from rpm binary packages}

{\bf Note}
Before start using Baculum API and Baculum Web version 9.0.0 please backup
your Bacula configuration in safe place. It is specially important because
on first save config action the Bacula configuration is joined into one file
per Bacula component.\\

For rpm binary there are the following packages:

\begin{itemize}
\item baculum-api - main Baculum API package with application files
\item baculum-api-httpd - Apache web server configuration files for Baculum API
\item baculum-api-lighttpd - Lighttpd web server configuration files for Baculum API
\item baculum-common - Common files for Baculum API and Baculum Web
\item baculum-web - main Baculum Web package with application files
\item baculum-web-httpd - Apache web server configuration files for Baculum Web
\item baculum-web-lighttpd - Lighttpd web server configuration files for Baculum Web
\end{itemize}

\subsection{Add the Baculum rpm repository}

To add the Baculum repository, first you must import the Baculum public key:

\begin{verbatim}
rpm --import http://bacula.org/downloads/baculum/baculum.pub
\end{verbatim}

Once the key is imported, the next step is to add the repository
definition.  First you must create the following file:

\begin{verbatim}
/etc/yum.repos.d/baculum.repo
\end{verbatim}

The for CentOS 7, put the following in the file just created:

\begin{verbatim}
[baculumrepo]
name=Baculum CentOS repository
baseurl=http://bacula.org/downloads/baculum/stable/centos
gpgcheck=1
enabled=1
\end{verbatim}

For Fedora 29 the {\bf bacula.repo} file should have the following contents:

\begin{verbatim}
[baculumrepo]
name=Baculum Fedora repository
baseurl=http://bacula.org/downloads/baculum/stable/fedora
gpgcheck=1
enabled=1
\end{verbatim}

\subsection{Installation for the Apache}

Install the Baculum API for the Apache Web server as follows:

\begin{verbatim}
yum install baculum-common baculum-api baculum-api-httpd
\end{verbatim}

Restart your Apache Web server:

\begin{verbatim}
service httpd restart
\end{verbatim}


\subsection{Installation for Lighttpd}

Installation on system with access via Lighttpd is as follows

\begin{verbatim}
yum install baculum-common baculum-api baculum-api-lighttpd
\end{verbatim}

Please note that in case CentOS distribution the Lighttpd web server is
available in the distribution packages after enabling the EPEL repository.

Start Baculum as application using the Lighttpd Web server:

\begin{verbatim}
service baculum-api-lighttpd start
\end{verbatim}

\subsection{Access to bconsole via sudo for Apache and Lighttpd}

Baculum API requires access to Bconsole and to Bacula JSON programs.
To configure Bconsole sudo access and the Bacula JSON programs access
there can use following entries in newly created Baculum sudoers.d file
(usually in path /etc/sudoers.d/baculum):\\

In case default Apache user, the file contents must be:

\begin{verbatim}
Defaults:apache !requiretty
apache  ALL=NOPASSWD:  /usr/sbin/bconsole
apache  ALL=NOPASSWD:  /usr/sbin/bdirjson
apache  ALL=NOPASSWD:  /usr/sbin/bsdjson
apache  ALL=NOPASSWD:  /usr/sbin/bfdjson
apache  ALL=NOPASSWD:  /usr/sbin/bbconsjson
\end{verbatim}

In case default Lighttpd user the file contents must be:

\begin{verbatim}
Defaults:lighttpd !requiretty
lighttpd  ALL=NOPASSWD:  /usr/sbin/bconsole
lighttpd  ALL=NOPASSWD:  /usr/sbin/bdirjson
lighttpd  ALL=NOPASSWD:  /usr/sbin/bsdjson
lighttpd  ALL=NOPASSWD:  /usr/sbin/bfdjson
lighttpd  ALL=NOPASSWD:  /usr/sbin/bbconsjson
\end{verbatim}

\section{Installation Baculum API from deb binary packages}

{\bf Note}
Before start using Baculum API and Baculum Web version 9.0.0 please backup
your Bacula configuration in safe place. It is specially important because
on first save config action the Bacula configuration is joined into one file
per Bacula component.\\

For deb binary there are the following packages:

\begin{itemize}
\item baculum-api - main Baculum API package with application files
\item baculum-api-apache2 - Apache web server configuration files for Baculum API
\item baculum-api-lighttpd - Lighttpd web server configuration files for Baculum API
\item baculum-common - Common files for Baculum API and Baculum Web
\item baculum-web - main Baculum Web package with application files
\item baculum-web-apache2 - Apache web server configuration files for Baculum Web
\item baculum-web-lighttpd - Lighttpd web server configuration files for Baculum Web
\end{itemize}

\subsection{Add the Baculum deb repository}

To add the Baculum repository, first import the Baculum public key:

\begin{verbatim}
wget -qO - http://bacula.org/downloads/baculum/baculum.pub | apt-key add -
\end{verbatim}

Once the key is imported, the next step is to create
a new baculum file:

\begin{verbatim}
/etc/apt/sources.list.d/baculum.list
\end{verbatim}

For Debian 8 Jessie the contents should be:

\begin{verbatim}
deb http://bacula.org/downloads/baculum/stable/debian jessie main
deb-src http://bacula.org/downloads/baculum/stable/debian jessie main
\end{verbatim}

For Debian 9 Stretch the contents should be:

\begin{verbatim}
deb http://bacula.org/downloads/baculum/stable/debian stretch main
deb-src http://bacula.org/downloads/baculum/stable/debian stretch main
\end{verbatim}

For Ubuntu 16.04 Xenial the contents should be:
\begin{verbatim}
deb [ arch=amd64 ] http://bacula.org/downloads/baculum/stable/ubuntu xenial main
deb-src http://bacula.org/downloads/baculum/stable/ubuntu xenial main
\end{verbatim}

For Ubuntu 18.04 Bionic the contents should be:
\begin{verbatim}
deb [ arch=amd64 ] http://bacula.org/downloads/baculum/stable/ubuntu bionic main
deb-src http://bacula.org/downloads/baculum/stable/ubuntu bionic main
\end{verbatim}

After adding repository definition, please refresh repository indexes:
\begin{verbatim}
apt-get update
\end{verbatim}

\subsection{Installation for Apache}

To install Baculum API access via Apache Web server by using apt
packages manager use the command:

\begin{verbatim}
apt-get install baculum-common baculum-api baculum-api-apache2
\end{verbatim}

Next you must enable mod\_rewrite module for Apache, with the
following command:

\begin{verbatim}
a2enmod rewrite
\end{verbatim}

and include Baculum VirtualHost definition in the Apache configuration
with:

\begin{verbatim}
a2ensite baculum-api
\end{verbatim}

The restart your Apache server with:

\begin{verbatim}
service apache2 restart
\end{verbatim}

\subsection{Installation for Lighttpd}

Example installation with access via Lighttpd web server looks following:

\begin{verbatim}
apt-get install baculum-common baculum-api baculum-api-lighttpd
\end{verbatim}

Start Baculum API as application available through Lighttpd web server:

\begin{verbatim}
service baculum-api-lighttpd start
\end{verbatim}

\subsection{Access to bconsole via sudo for Apache and Lighttpd}

Baculum API requires access to Bconsole and to the Bacula JSON programs.
To configure Bconsole sudo access we strongly recommend that you create
a Baculum sudoers.d file, which should be in /etc/sudoers.d/baculum:

{\bf Note}, please define sudo for the Bacula JSON programs only when
you are going use Bacula configuration module in the Baculum.

Both for Apache and Lighttpd user the file contents can be:

\begin{verbatim}
Defaults:www-data !requiretty
www-data  ALL=NOPASSWD:  /usr/sbin/bconsole
www-data  ALL=NOPASSWD:  /usr/sbin/bdirjson
www-data  ALL=NOPASSWD:  /usr/sbin/bsdjson
www-data  ALL=NOPASSWD:  /usr/sbin/bfdjson
www-data  ALL=NOPASSWD:  /usr/sbin/bbconsjson
\end{verbatim}

\section{Debugging your First Baculum API Login}
At each step of the initial login to Baculum, the
screen will have a test button that will allow you
to check to see if your parameters were correctly
entered.  If not, you will see error message on the
wizard page. You can also get additional detail by
examining the Apache error log, that is usually
found at:

\begin{verbatim}
/var/log/httpd/baculum-api-error.log
\end{verbatim}

If you use Lighttpd thento get additional detail you can check:

\begin{verbatim}
/var/log/lighttpd/baculum-api-error.log
\end{verbatim}

In addition, special debug output is placed by Baculum in
the file:

\begin{verbatim}
/usr/share/baculum/htdocs/protected/API/Logs/baculum-api.log
\end{verbatim}

The debug you can enable in file:
\begin{verbatim}
/usr/share/baculum/htdocs/protected/API/Config/api.conf
\end{verbatim}

by switching in [api] section option debug to "1".

With the information in those two files, you can usually quickly
find and correct most problems.



\section{Installation Baculum Web from rpm binary packages}

\subsection{Installation for the Apache}

Install the Baculum Web for the Apache Web server as follows:

\begin{verbatim}
yum install baculum-common baculum-web baculum-web-httpd
\end{verbatim}

Restart your Apache Web server:

\begin{verbatim}
service httpd restart
\end{verbatim}

\subsection{Installation for Lighttpd}

Installation on system with access via Lighttpd is as follows

\begin{verbatim}
yum install baculum-common baculum-web baculum-web-lighttpd
\end{verbatim}

Please note that in case CentOS distribution the Lighttpd web server is
available in the distribution packages after enabling the EPEL repository.

Start Baculum as application using the Lighttpd Web server:

\begin{verbatim}
service baculum-web-lighttpd start
\end{verbatim}

\section{Installation Baculum Web from deb binary packages}

\subsection{Installation for Apache}

To install Baculum Web access via Apache Web server by using apt
packages manager use the command:

\begin{verbatim}
apt-get install baculum-common baculum-web baculum-web-apache2
\end{verbatim}

Next you must enable mod\_rewrite module for Apache, with the
following command:

\begin{verbatim}
a2enmod rewrite
\end{verbatim}

and include Baculum VirtualHost definition in the Apache configuration
with:

\begin{verbatim}
a2ensite baculum-web
\end{verbatim}

The restart your Apache server with:

\begin{verbatim}
service apache2 restart
\end{verbatim}

\subsection{Installation for Lighttpd}

Example installation with access via Lighttpd web server looks following:

\begin{verbatim}
apt-get install baculum-common baculum-web baculum-web-lighttpd
\end{verbatim}

Start Baculum Web as application available through Lighttpd web server:

\begin{verbatim}
service baculum-web-lighttpd start
\end{verbatim}

\section{Running Baculum API and Web for the First Time}

\subsection{Running Baculum API}

Access to Baculum API from web browser: \textbf{http://localhost:9096}

First time login: \textbf{admin}

First time password: \textbf{admin}


\subsection{Running Baculum Web}

Access to Baculum Web from web browser: \textbf{http://localhost:9095}

First time login: \textbf{admin}

First time password: \textbf{admin}

\section{Installation wizards}

\textbf{Installation with HTTP Basic authentication}

\includegraphics[width=\linewidth]{baculum_install_basic.png}

\smallskip

\textbf{Installation with OAuth2 authorization}

\includegraphics[width=\linewidth]{baculum_install_oauth2.png}

\smallskip

\section{Current Baculum API documentation}

The most actual Baculum API documentation is placed at the following link:

\elink{Baculum API documentation}{https://bacula.org/downloads/baculum/baculum-api/}

\section{Baculum API endpoints (obsolete)}

\subsection{Clients}

GET /api/clients - get records all clients

GET /api/clients/limit/4 - get records first 4 clients

GET /api/clients/2 - get records only for client with clientid equal 2

GET /api/clients/show  - get 'show clients' bconsole command

GET /api/clients/show/2 - get 'show client=xxx' bconsole command for client with clientid equal 2

GET /api/clients/status/2 - get 'status client=xxx' bconsole command for client with clientid equal 2

GET /api/clients/jobs/2 - get all jobs done by client with clientid equal 2\\


Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

10 - Client with inputted clientid does not exists.

11 - Bconsole support is disabled.

1000 - Internal error.

\subsection{Storages}

GET /api/storages/ - get records all storages.

GET /api/storages/limit/25 - get records first 25 storages.

GET /api/storages/3 - get records only for storage with storageid equal 3.

GET /api/storages/show - get 'show storages' bconsole command.

GET /api/storages/show/3 - get 'show storage=xxx' bconsole command for storage with storageid equal 3.

GET /api/storages/status/3 - get 'status storage=xxx' bconsole command for storage with storageid equal 3.

GET /api/storages/mount/3/2/17 - mount storage with storageid equal 3, drive number 2 and volume in slot number 17.

GET /api/storages/umount/3/1 - umount storage with storageid equal 3 and drive number 1.

GET /api/storages/release/3 - release storage with storageid equal 3.\\


Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

11 - Bconsole support is disabled.

20 - Storage with inputted storageid does not exists.

1000 - Internal error.

\subsection{Volumes}

GET /api/volumes/ - get records all volumes.

GET /api/volumes/limit/50 - get records first 50 volumes.

GET /api/volumes/5 - get records only for volume with mediaid equal 5.

GET /api/volumes/prune/5 - call prune action on volume with mediaid equal 5.

GET /api/volumes/purge/5 - call purge action on volume with mediaid equal 5.

GET /api/volumes/jobs/5 - get all jobs done on volume with mediaid equal 5.\\

GET /api/volumes/required/7/1234/ - get all volumes required to restore file
 with fileid equal 1234 and jobid equal 7.


Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

11 - Bconsole support is disabled.

30 - Volume with inputted mediaid does not exists.

1000 - Internal error.

\subsection{Pools}

GET /api/pools/ - get records all pools.

GET /api/pools/limit/15 - get records first 15 pools.

GET /api/pools/7 - get records only for pool with poolid equal 7.

GET /api/pools/show - get 'show pools' bconsole command.

GET /api/pools/show/7 - get 'show pool=xxx' bconsole command for pool with poolid equal 7.

PUT /api/pools/update/7 - call 'update pool=xxx' bconsole command for pool with poolid equal 7.\\


Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

11 - Bconsole support is disabled.

40 - Pool with inputted poolid does not exists.

1000 - internal error.\\

\subsection{Jobs}

GET /api/jobs/ - get records all jobs.

GET /api/jobs/limit/20 - get records first 20 jobs.

GET /api/jobs/8 - get records only for job with jobid equal 8.

GET /api/jobs/tasks/ - get job names for all directors

GET /api/jobs/tasks/type/B - get backup job names

GET /api/jobs/tasks/type/R/limit/5 - get first 5 restore job names

GET /api/jobs/recent/myjob/client/myclient-fd/filesetid/62/ - get most
recent job identifiers for job "myjob", client "myclient-fd" and fileset
with filesetid 62

GET /api/jobs/recent/myjob/clientid/31/filesetid/62/ - get most
recent job identifiers for job "myjob", client with clientid 21 and fileset
with filesetid 62

POST /jobs/estimate/ - call estimate action on a job.

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/jobs/estimate/ POST request                       |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| create[id] *      | integer | job id to get job name for estimate purpose   |
|                   |         | (used instead job name)                       |
+-------------------+---------+-----------------------------------------------+
| create[name] *    | string  | job name to estimate (used instead of jobid)  |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[fileset] * | string  | FileSet resource name                         |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[level] *   | string  | Job level in short form.                      |
|                   |         | One case sensitive letter:                    |
|                   |         |    F => Full                                  |
|                   |         |    I => Incremental                           |
|                   |         |    D => Differential                          |
|                   |         |    B => Base                                  |
|                   |         |    f => VirtualFull                           |
|                   |         |    V => InitCatalog                           |
|                   |         |    C => Catalog                               |
|                   |         |    O => VolumeToCatalog                       |
|                   |         |    d => DiskToCatalog                         |
+-------------------+---------+-----------------------------------------------+
| create[clientid] *| integer | Client identifier                             |
|                   |         | (used instead of client name)                 |
+-------------------+---------+-----------------------------------------------+
| create[client] *  | string  | Client name (used instead of client id)       |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[accurate] *| integer | Enable accurate mode: 0 - no, 1 - yes         |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+

* - required field
\end{verbatim}

POST /api/jobs/run/ - call run action on job (run job).

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/jobs/run/ POST request                            |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| create[id] *      | integer | job id to get job name to run                 |
|                   |         | (used instead job name)                       |
+-------------------+---------+-----------------------------------------------+
| create[name] *    | string  | job name to run (used instead of jobid)       |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[level] *   | string  | Job level in short form.                      |
|                   |         | One case sensitive letter:                    |
|                   |         |    F => Full                                  |
|                   |         |    I => Incremental                           |
|                   |         |    D => Differential                          |
|                   |         |    B => Base                                  |
|                   |         |    f => VirtualFull                           |
|                   |         |    V => InitCatalog                           |
|                   |         |    C => Catalog                               |
|                   |         |    O => VolumeToCatalog                       |
|                   |         |    d => DiskToCatalog                         |
+-------------------+---------+-----------------------------------------------+
| create[fileset] * | string  | FileSet resource name                         |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[clientid] *| integer | Client identifier                             |
|                   |         | (used instead of client name)                 |
+-------------------+---------+-----------------------------------------------+
| create[client] *  | string  | Client name (used instead of client id)       |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[storageid]*| integer | Storage identifier                            |
|                   |         | (used instead of storage name)                |
+-------------------+---------+-----------------------------------------------+
| create[storage] * | string  | Storage name (used instead of storage id)     |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[poolid] *  | integer | Pool identifier (used instead of pool name)   |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[pool] *    | string  | Pool name (used instead of pool id)           |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[priority]  | integer | Job priority to run                           |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[jobid]     | integer | Job identifier for verify job                 |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[verifyjob] | string  | Verify job name                               |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+

* - required field
\end{verbatim}

POST /api/jobs/restore/ - call restore action.

\begin{verbatim}
+-------------------------------------------------------------------------------+
|                       /api/jobs/restore/ POST request                         |
+---------------------+---------+-----------------------------------------------+
| Name                |  Type   |    Description                                |
+---------------------+---------+-----------------------------------------------+
| create[rpath] *     | string  | Bvfs temporary table name for restore purpose |
|                     |         | in form: b2[0-9]+                             |
+---------------------+---------+-----------------------------------------------+
| create[clientid] *  | integer | Client identifier                             |
|                     |         | (used instead of client name)                 |
+---------------------+---------+-----------------------------------------------+
| create[client] *    | string  | Client name (used instead of client id)       |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[priority]    | integer | Job priority to run                           |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[where] *     | string  | Destination directory for restored files      |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[replace] *   | string  | Replace files in destination directory for    |
|                     |         | restored files. Available options:            |
|                     |         | - never                                       |
|                     |         | - ifolder                                     |
|                     |         | - ifnewer                                     |
|                     |         | - always                                      |
+---------------------+---------+-----------------------------------------------+
| create[restorejob]  | string  | Restore job name                              |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[strip_prefix]| string  | Strip prefix from restored paths /etc         |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[add_prefix]  | string  | Add prefix to restored paths /tmp/myetc       |
|                     |         | It can't be used with 'where' parameter       |
+---------------------+---------+-----------------------------------------------+
| create[add_suffix]  | string  | Add suffix to restored path e.g. .old         |
|                     |         |                                               |
+---------------------+---------+-----------------------------------------------+
| create[regex_where] | string  | Pattern matched for each restored path        |
|                     |         | e.g. !a.pdf!a.bkp.pdf!                        |
+---------------------+---------+-----------------------------------------------+

* - required field
\end{verbatim}

DELETE /api/jobs/8 - delete by bconsole job with jobid equal 8.\\

Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

11 - Bconsole support is disabled.

50 - Job with inputted jobid does not exist.

51 - Inputed job level is invalid.

52 - Fileset resource does not exist.

53 - Client does not exist.

54 - Storage does not exist.

55 - Pool does not exist.

56 - [restore only] inputted rpath for restore is invalid. Proper format
is b2[0-9]+.

57 - [restore only] inputted "where" option is invalid.

58 - [restore only] inputted "replace" option is invalid.

1000 - internal error.\\

\subsection{Bvfs}

PUT /api/bvfs/lsdirs/ - listing from Bvfs cache directories

PUT /api/bvfs/lsdirs/limit/250 - listing from Bvfs cache directories
 limited to 250 elements.

PUT /api/bvfs/lsdirs/limit/250/100/ - listing from Bvfs cache directories
 limited to 250 elements with offset equal 100.

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/bvfs/lsdirs/ PUT request                          |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| update[jobids] *  | string  | Job identifiers separated by comma character  |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| update[path] *    | string  | Path to list directories in Bvfs job cache    |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
\end{verbatim}

PUT /api/bvfs/lsfiles/ - listing from Bvfs cache files.

PUT /api/bvfs/lsfiles/limit/60/ - listing from Bvfs cache files limited
 to 60 elements.

PUT /api/bvfs/lsfiles/limit/120/60/ - listing from Bvfs cache files limited
 to 120 elements with offset equal 60

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/bvfs/lsfiles/ PUT request                         |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| update[jobids] *  | string  | Job identifiers separated by comma character  |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| update[path] *    | string  | Path to list directories in Bvfs job cache    |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
\end{verbatim}

GET /api/bvfs/versions/abc-fd/123/456/789/ - listing from Bvfs cache all
 files versions for client named abc-fd, for jobid equal 123, for pathid
equal 456 and for filenameid equal 789. URL-encoded client name is necessary.

GET /api/bvfs/getjobids/9/ - listing from Bvfs cache all elementary jobids which
 are necessary for restore all files from job with jobid equal 9 (eg. if jobid 9
  is job type incremental or differential).

PUT /api/bvfs/update/ - updating Bvfs cache for specific job.

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/bvfs/update/ PUT request                          |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| update[jobids] *  | string  | Job identifiers separated by comma character  |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
\end{verbatim}

POST /api/bvfs/restore/ - preparing Bvfs paths for restore command.

\begin{verbatim}
+-----------------------------------------------------------------------------+
|                      /api/bvfs/restore/ POST request                        |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| create[jobids] *  | string  | job identifiers comma separated               |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[dirid]     | string  | directory identifiers comma separated         |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[fileid]    | string  | file identifiers comma separated              |
|                   |         |                                               |
+-------------------+---------+-----------------------------------------------+
| create[findex]    | string  | comma separated pairs jobid and fileindex e.g.|
|                   |         | jobid1,findex1,jobid2,findex2                 |
|                   |         | Used to restore hardlinks                     |
+-------------------+---------+-----------------------------------------------+
| create[path] *    | string  | temporary Bvfs table table name               |
|                   |         | in form b2[0-9]+                              |
+-------------------+---------+-----------------------------------------------+

* - required field
\end{verbatim}

PUT /api/bvfs/clear/ - call '.bvfs\_clear\_cache yes' bconsole command.\\


Errors:

0 - No errors.

1 - Invalid command.

2 - Problem with connection to database.

3 - Database access is not supported by this API instance.

4 - Problem with connection to bconsole.

5 - Invalid director.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

11 - Bconsole support is disabled.

71 - Inputted path for restore is invalid. Proper format is b2[0-9]+.

72 - Inputted BVFS path param is invalid.

73 - Invalid jobid list.

74 - Invalid fileid list.

75 - Invalid file index list.

76 - Invalid dirid list.

77 - Invalid client name.

1000 - Internal error.

\subsection{Config}

To configure the Bacula resources is used request in the following URL form:\\

PUT /api/config/COMPONENT\_TYPE/RESOURCE\_TYPE/RESOURCE\_NAME

\begin{itemize}
\item COMPONENT\_TYPE: dir for Director, sd for Storage Daemon, fd for
 File Daemon and bcons for Consoles
\item RESOURCE\_TYPE: Job, Client, Pool, Messages, Schedule, Storage...etc.
\item RESOURCE\_NAME: Resource name from 'Name' resource directive like
 'My Client 123', 'Device-01', 'Pool-Incremental-2' ...etc.
\end{itemize}

Example config URLs:\\

PUT /api/config/dir/Client/myclient-fd - editing client 'myclient-fd'. If
 the Client doesn't exist, it is created in config.

PUT /api/config/sd/Device/Drive-01 - editing device 'Drive-01'. If
 the Device doesn't exist, it is created in config.

\begin{verbatim}
+-----------------------------------------------------------------------------+
|    /api/config/component_type/resource_type/resource_name/ PUT request      |
+-------------------+---------+-----------------------------------------------+
| Name              |  Type   |    Description                                |
+-------------------+---------+-----------------------------------------------+
| update[config] *  | string  | Bacula config in JSON format.                 |
|                   | (JSON)  |                                               |
|                   |         | In versions lower than 9.0.6 instead of JSON  |
|                   |         | string there was used serialized associative  |
|                   |         | PHP array                                     |
+-------------------+---------+-----------------------------------------------+

* - required field
\end{verbatim}

Errors:

0 - No errors.

6 - Problem with authorization to Baculum API.

7 - Access attempt to not allowed resource. Permission denied.

80 - JSON tools support is disabled.

81 - Problem with connection to a JSON tool.

82 - JSON tool returned wrong exitcode.

83 - JSON tool output was unable to parse.

84 - JSON tool not configured.

93 - Write to config file error.

94 - Config validation error.

1000 - Internal error.\\


Example cURL commands to test:

\begin{verbatim}
curl -X PUT -d update["config"]='{"AutoPrune":false,"Catalog":"MyCatalog",
"FdPort":9102,"MaximumConcurrentJobs":5,"Name":"easystar-fd","Address":
"172.16.10.12","Password":"mypass"}'
 http://user:pass@apihost:9096/api/config/dir/Client/easystar-fd

curl -X PUT -d update["config"]='{"RemovableMedia":true,"RandomAccess":false,
"AutomaticMount":true,"AlwaysOpen":true,"OfflineOnUnmount":true,"DeviceType":
"Tape","Name":"TapeDrive","MediaType":"LTO5","ArchiveDevice":"/dev/nst0",
"SpoolDirectory":"/mnt/backup","MaximumOpenWait":300}'
 http://user:pass@apihost:9096/api/config/sd/Device/TapeDrive
\end{verbatim}

\section{Installation from the Source Tar File}

You may also install Baculum from the source bacula-gui tar archive.

To prepare Baculum runtime files one uses the Makefile file.
To do this, after unpacking bacula-gui archive please go to Baculum main
directory:

\begin{verbatim}
cd ./web/baculum/
\end{verbatim}

Then please run (depending on used distribution):

For rpm-based distributions (example with /tmp/baculum-runtime destination
directory):

\begin{verbatim}
make build DESTDIR=/tmp/baculum-runtime
\end{verbatim}

For deb-based distributions (example with /tmp/baculum-runtime destination
directory):

\begin{verbatim}
make build DESTDIR=/tmp/baculum-release SAMPLETYPE=deb-template \
HTTPDNAME=apache2 HTTPDSITECONF=sites-available
\end{verbatim}

After execution above command, in path /tmp/baculum-runtime should
contain all required runtime files.

The Base Baculum source files will be located in:

\begin{verbatim}
/tmp/baculum-runtime/usr/share/baculum/htdocs/
\end{verbatim}

These are the files that should be placed in web server's document root (or
Virtual Host document root) directory.

Please note that for language files (including English)
symbolic links must be created as shown below:

\begin{verbatim}
/usr/share/locale/en/LC_MESSAGES/baculum.mo
 => /tmp/baculum-runtime/usr/share/baculum/htdocs/protected/Lang/en/baculum.mo

/usr/share/locale/pl/LC_MESSAGES/baculum.mo
 => /tmp/baculum-runtime/usr/share/baculum/htdocs/protected/Lang/pl/baculum.mo

/usr/share/locale/pt/LC_MESSAGES/baculum.mo
 => /tmp/baculum-runtime/usr/share/baculum/htdocs/protected/Lang/pt/baculum.mo

/usr/share/locale/ja/LC_MESSAGES/baculum.mo
 => /tmp/baculum-runtime/usr/share/baculum/htdocs/protected/Lang/ja/baculum.mo
\end{verbatim}

Please also update the symbolic link to the Baculum settings directory in
the following paths:

\begin{verbatim}
/tmp/baculum-runtime/usr/share/baculum/htdocs/protected/API/Config
/tmp/baculum-runtime/usr/share/baculum/htdocs/protected/Web/Config
\end{verbatim}

Other files are: web servers configuration files, systemd units, SELinux
policy module and others. Please select and copy appropriate files to your
system environment and edit their content if needed.

You must set read/write privileges for the Web server user
to the files and directories listed below:

\begin{verbatim}
./baculum/assets/
./baculum/protected/Web/Config
./baculum/protected/API/Config
./baculum/protected/Web/baculum.users
./baculum/protected/API/baculum.users
./baculum/protected/runtime/
\end{verbatim}

\section{OAuth2 authorization}

Baculum API can use OAuth2 for authorization and authentication.

To obtain tokens there is used {\bf Authorization Code Grant} flow.
Authorization and access token URLs are as follows:

\begin{verbatim}
Authorization URL: /api/auth/
Access Token URL: /api/token/
\end{verbatim}

Baculum API doesn't use refresh tokens. After expiration token the client
application has to re-authorize again.

Default expiration time for authorization code is 7 seconds, for access
token 60 seconds. These values are changed in:

\begin{verbatim}
/usr/share/baculum/htdocs/protected/Common/Class/OAuth2.php
\end{verbatim}

in constants AUTHORIZATION\_ID\_EXPIRES\_TIME and ACCESS\_TOKEN\_EXPIRES\_TIME.

Default OAuth2 callback URL in Baculum Web is following:

\begin{verbatim}
https://baculumgui:9095/web/redirect
\end{verbatim}

\subsection{Before running OAuth2}

{\bf Important note before using OAuth2}

When you decide to use OAuth2, you must change default HTTP Basic authorization
setting. Otherwise OAuth2 will not work. It is for enabling OAuth2 acces for
/api/ endpoints but still keep HTTP Basic protection for the Baculum API panel
pages.

For Apache the change is about switching in Baculum API Apache config
the Location tag from / to /api/page.

\begin{verbatim}
#
# NOTE: When you use OAuth2 then change this Directory section
# From: <Directory /usr/share/baculum/htdocs>
#            ...section body...
#       </Directory>
# To:   <Location /api/page>
#            ...section body...
#       </Location>
#
<Directory /usr/share/baculum/htdocs>
#<Location /api/page>
        AuthType Basic
        AuthName "Baculum Auth"
        AuthUserFile /usr/share/baculum/htdocs/protected/API/Config/baculum.users
        Require valid-user
#</Location>
</Directory>

\end{verbatim}


For Lighttpd the change is about uncommenting in API Lighttpd config lines as
described in comment below.

\begin{verbatim}
#
# Uncomment this line and closing braces below when you use OAuth2
#
# $HTTP["url"] =~ "^/web/page/.*$" {
        auth.backend = "htpasswd"
        auth.backend.htpasswd.userfile = "/usr/share/baculum/htdocs/protected/API/Config/baculum.users"
        auth.require = ( "/" => (
                "method" => "basic",
                "realm" => "Baculum Auth",
                "require" => "valid-user"
                )
        )
# }
\end{verbatim}

\section{Multi-user interface}

Baculum enables access to Bacula resources for defined users where every
user uses own resources (Jobs, Clients, FileSets ...etc.). These resources
are assigned to users by the Bacula Restricted Consoles and then they are
used by Baculum.

To setup this multi-user interface there is needed to enable the OAuth2
authorization on Baculum API hosts that are used by the Baculum Web interface.
There is also necessarily to define in the Director configuration Console
resources for users and dedicated for them Bconsole config files.

Minimal Console resource configuration can look as below. These {\bf CommandAcl}
values in the configuration are required to proper working all available
functions for normal Baculum users (run job, restore backup, cancel job,
delete job and others).

\begin{verbatim}
Console {
  Name = "Limited User 144"
  Password = "A6cTimESfLs7xPNOMC/ein92BF4="
  JobAcl = "BackupCatalog"
  JobAcl = "RestoreFiles"
  ClientAcl = "myhost-fd"
  StorageAcl = "File1"
  PoolAcl = "File"
  CommandAcl = "gui"
  CommandAcl = ".jobs"
  CommandAcl = ".client"
  CommandAcl = ".fileset"
  CommandAcl = ".pool"
  CommandAcl = ".storage"
  CommandAcl = ".bvfs_get_jobids"
  CommandAcl = ".bvfs_update"
  CommandAcl = ".bvfs_lsdirs"
  CommandAcl = ".bvfs_lsfiles"
  CommandAcl = ".bvfs_versions"
  CommandAcl = ".bvfs_restore"
  CommandAcl = ".bvfs_cleanup"
  CommandAcl = "restore"
  CommandAcl = "show"
  CommandAcl = "estimate"
  CommandAcl = "run"
  CommandAcl = "delete"
  CommandAcl = "cancel"
  FilesetAcl = "Full Set"
  CatalogAcl = "MyCatalog"
  WhereAcl = "/tmp/restore"
}
\end{verbatim}

Assigning Restricted Consoles to users is realized during configuring OAuth2
accounts on API hosts panel as on attached screen shot.

\includegraphics[width=\linewidth]{baculum_add_oauth2_user_account.png}

Please note that in the OAuth2 scopes there is not "config" scope defined
because normal users don't have access to configuring Bacula resources by
Baculum API hosts.

Once the OAuth2 accounts with assigned dedicated consoles are done, now you
can connect Baculum Web to those new Baculum API OAuth2 accounts.

\includegraphics[width=\linewidth]{baculum_add_new_api_host.png}

At the end there is needed to create Baculum Web users and assign them
to appropriate OAuth2 user accounts on API hosts.

\includegraphics[width=\linewidth]{baculum_define_and_assign_users_to_api_hosts.png}

Images below show difference between access to Baculum API hosts and to resources
by normal users and by admin user.

\includegraphics[width=\linewidth]{baculum_multi_user_admin_mode.png}

\smallskip

\includegraphics[width=\linewidth]{baculum_multi_user_user_mode.png}

Normal (non-admin) user interface can look as on screen shot:

\includegraphics[width=\linewidth]{baculum_normal_user_dashboard.png}

\section{Screenshots}

\includegraphics[width=\linewidth]{baculum01.png}

\smallskip

\includegraphics[width=\linewidth]{baculum02.png}

\smallskip

\includegraphics[width=\linewidth]{baculum03.png}

\smallskip

\includegraphics[width=\linewidth]{baculum04.png}

\smallskip

\includegraphics[width=\linewidth]{baculum05.png}

\smallskip

\includegraphics[width=\linewidth]{baculum06.png}

\smallskip

\includegraphics[width=\linewidth]{baculum07.png}
