From: Marcin Haba Date: Tue, 13 Jul 2021 03:00:21 +0000 (+0200) Subject: baculum: New copy job wizard X-Git-Tag: Release-11.3.2~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1eda9ab528cba8f98fef84ff5facf64aa7c20beb;p=thirdparty%2Fbacula.git baculum: New copy job wizard --- diff --git a/gui/baculum/protected/Web/Lang/en/messages.mo b/gui/baculum/protected/Web/Lang/en/messages.mo index a131ef6c1..2cd01f7e4 100644 Binary files a/gui/baculum/protected/Web/Lang/en/messages.mo and b/gui/baculum/protected/Web/Lang/en/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/en/messages.po b/gui/baculum/protected/Web/Lang/en/messages.po index 52e4d16c4..70e007b05 100644 --- a/gui/baculum/protected/Web/Lang/en/messages.po +++ b/gui/baculum/protected/Web/Lang/en/messages.po @@ -3460,3 +3460,132 @@ msgstr "Previous error/warning" msgid "Next error/warning" msgstr "Next error/warning" + +msgid "New backup job" +msgstr "New backup job" + +msgid "New copy job" +msgstr "New copy job" + +msgid "Step 1 - basic information about new job" +msgstr "Step 1 - basic information about new job" + +msgid "New copy job wizard" +msgstr "New copy job wizard" + +msgid "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." +msgstr "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." + +msgid "Step 2 - what you want to copy" +msgstr "Step 2 - what you want to copy" + +msgid "Source Pool" +msgstr "Source Pool" + +msgid "Please select a pool from which you want to copy data." +msgstr "Please select a pool from which you want to copy data." + +msgid "The source pool will be examined for finding backup jobs to copy." +msgstr "The source pool will be examined for finding backup jobs to copy." + +msgid "See volumes in selected pool" +msgstr "See volumes in selected pool" + +msgid "Step 3 - how would you like to copy" +msgstr "Step 3 - how would you like to copy" + +msgid "Backup jobs selection criteria" +msgstr "Backup jobs selection criteria" + +msgid "Please select the criteria that will be used for selecting backup jobs to copy." +msgstr "Please select the criteria that will be used for selecting backup jobs to copy." + +msgid "Copy by job" +msgstr "Copy by job" + +msgid "Copy by client" +msgstr "Copy by client" + +msgid "Copy by volume" +msgstr "Copy by volume" + +msgid "Copy by smallest volume" +msgstr "Copy by smallest volume" + +msgid "Copy by oldest volume" +msgstr "Copy by oldest volume" + +msgid "Copy by SQL query" +msgstr "Copy by SQL query" + +msgid "Copy all uncopied jobs (Pool Uncopied Jobs)" +msgstr "Copy all uncopied jobs (Pool Uncopied Jobs)" + +msgid "See backup jobs" +msgstr "See backup jobs" + +msgid "See clients" +msgstr "See clients" + +msgid "See volumes" +msgstr "See volumes" + +msgid "Warning" +msgstr "Warning" + +msgid "Note." +msgstr "Note." + +msgid "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" +msgstr "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" + +msgid "See all jobs that use the pool" +msgstr "See all jobs that use the pool" + +msgid "Step 4 - where you like to copy" +msgstr "Step 4 - where you like to copy" + +msgid "Destination Pool" +msgstr "Destination Pool" + +msgid "Please select destination pool to which will be stored data." +msgstr "Please select destination pool to which will be stored data." + +msgid "Destination Storage" +msgstr "Destination Storage" + +msgid "Step 5 - copy job options" +msgstr "Step 5 - copy job options" + +msgid "Other options" +msgstr "Other options" + +msgid "Pick job name" +msgstr "Pick job name" + +msgid "Pick client name" +msgstr "Pick client name" + +msgid "Pick volume name" +msgstr "Pick volume name" + +msgid "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." +msgstr "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." + +msgid "Source Storage" +msgstr "Source Storage" + +msgid "Please select a storage using which you want to read copy data." +msgstr "Please select a storage using which you want to read copy data." + +msgid "Please select a storage using which you want to write copied data." +msgstr "Please select a storage using which you want to write copied data." + +msgid "Not used" +msgstr "Not used" + +msgid "New backup job wizard" +msgstr "New backup job wizard" + +msgid "This wizard enables you to create in easy way a new backup job." +msgstr "This wizard enables you to create in easy way a new backup job." diff --git a/gui/baculum/protected/Web/Lang/ja/messages.mo b/gui/baculum/protected/Web/Lang/ja/messages.mo index e18c9ba4d..960a676bb 100644 Binary files a/gui/baculum/protected/Web/Lang/ja/messages.mo and b/gui/baculum/protected/Web/Lang/ja/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/ja/messages.po b/gui/baculum/protected/Web/Lang/ja/messages.po index a7b487939..35e2c927e 100644 --- a/gui/baculum/protected/Web/Lang/ja/messages.po +++ b/gui/baculum/protected/Web/Lang/ja/messages.po @@ -3546,3 +3546,132 @@ msgstr "Previous error/warning" msgid "Next error/warning" msgstr "Next error/warning" + +msgid "New backup job" +msgstr "New backup job" + +msgid "New copy job" +msgstr "New copy job" + +msgid "Step 1 - basic information about new job" +msgstr "Step 1 - basic information about new job" + +msgid "New copy job wizard" +msgstr "New copy job wizard" + +msgid "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." +msgstr "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." + +msgid "Step 2 - what you want to copy" +msgstr "Step 2 - what you want to copy" + +msgid "Source Pool" +msgstr "Source Pool" + +msgid "Please select a pool from which you want to copy data." +msgstr "Please select a pool from which you want to copy data." + +msgid "The source pool will be examined for finding backup jobs to copy." +msgstr "The source pool will be examined for finding backup jobs to copy." + +msgid "See volumes in selected pool" +msgstr "See volumes in selected pool" + +msgid "Step 3 - how would you like to copy" +msgstr "Step 3 - how would you like to copy" + +msgid "Backup jobs selection criteria" +msgstr "Backup jobs selection criteria" + +msgid "Please select the criteria that will be used for selecting backup jobs to copy." +msgstr "Please select the criteria that will be used for selecting backup jobs to copy." + +msgid "Copy by job" +msgstr "Copy by job" + +msgid "Copy by client" +msgstr "Copy by client" + +msgid "Copy by volume" +msgstr "Copy by volume" + +msgid "Copy by smallest volume" +msgstr "Copy by smallest volume" + +msgid "Copy by oldest volume" +msgstr "Copy by oldest volume" + +msgid "Copy by SQL query" +msgstr "Copy by SQL query" + +msgid "Copy all uncopied jobs (Pool Uncopied Jobs)" +msgstr "Copy all uncopied jobs (Pool Uncopied Jobs)" + +msgid "See backup jobs" +msgstr "See backup jobs" + +msgid "See clients" +msgstr "See clients" + +msgid "See volumes" +msgstr "See volumes" + +msgid "Warning" +msgstr "Warning" + +msgid "Note." +msgstr "Note." + +msgid "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" +msgstr "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" + +msgid "See all jobs that use the pool" +msgstr "See all jobs that use the pool" + +msgid "Step 4 - where you like to copy" +msgstr "Step 4 - where you like to copy" + +msgid "Destination Pool" +msgstr "Destination Pool" + +msgid "Please select destination pool to which will be stored data." +msgstr "Please select destination pool to which will be stored data." + +msgid "Destination Storage" +msgstr "Destination Storage" + +msgid "Step 5 - copy job options" +msgstr "Step 5 - copy job options" + +msgid "Other options" +msgstr "Other options" + +msgid "Pick job name" +msgstr "Pick job name" + +msgid "Pick client name" +msgstr "Pick client name" + +msgid "Pick volume name" +msgstr "Pick volume name" + +msgid "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." +msgstr "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." + +msgid "Source Storage" +msgstr "Source Storage" + +msgid "Please select a storage using which you want to read copy data." +msgstr "Please select a storage using which you want to read copy data." + +msgid "Please select a storage using which you want to write copied data." +msgstr "Please select a storage using which you want to write copied data." + +msgid "Not used" +msgstr "Not used" + +msgid "New backup job wizard" +msgstr "New backup job wizard" + +msgid "This wizard enables you to create in easy way a new backup job." +msgstr "This wizard enables you to create in easy way a new backup job." diff --git a/gui/baculum/protected/Web/Lang/pl/messages.mo b/gui/baculum/protected/Web/Lang/pl/messages.mo index 903e7182f..4f546c04b 100644 Binary files a/gui/baculum/protected/Web/Lang/pl/messages.mo and b/gui/baculum/protected/Web/Lang/pl/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/pl/messages.po b/gui/baculum/protected/Web/Lang/pl/messages.po index 08a88c153..b59bf19e6 100644 --- a/gui/baculum/protected/Web/Lang/pl/messages.po +++ b/gui/baculum/protected/Web/Lang/pl/messages.po @@ -3470,3 +3470,132 @@ msgstr "Poprzedni błąd/ostrzeżenie" msgid "Next error/warning" msgstr "Następny błąd/ostrzeżenie" + +msgid "New backup job" +msgstr "New backup job" + +msgid "New copy job" +msgstr "New copy job" + +msgid "Step 1 - basic information about new job" +msgstr "Step 1 - basic information about new job" + +msgid "New copy job wizard" +msgstr "New copy job wizard" + +msgid "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." +msgstr "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." + +msgid "Step 2 - what you want to copy" +msgstr "Step 2 - what you want to copy" + +msgid "Source Pool" +msgstr "Source Pool" + +msgid "Please select a pool from which you want to copy data." +msgstr "Please select a pool from which you want to copy data." + +msgid "The source pool will be examined for finding backup jobs to copy." +msgstr "The source pool will be examined for finding backup jobs to copy." + +msgid "See volumes in selected pool" +msgstr "See volumes in selected pool" + +msgid "Step 3 - how would you like to copy" +msgstr "Step 3 - how would you like to copy" + +msgid "Backup jobs selection criteria" +msgstr "Backup jobs selection criteria" + +msgid "Please select the criteria that will be used for selecting backup jobs to copy." +msgstr "Please select the criteria that will be used for selecting backup jobs to copy." + +msgid "Copy by job" +msgstr "Copy by job" + +msgid "Copy by client" +msgstr "Copy by client" + +msgid "Copy by volume" +msgstr "Copy by volume" + +msgid "Copy by smallest volume" +msgstr "Copy by smallest volume" + +msgid "Copy by oldest volume" +msgstr "Copy by oldest volume" + +msgid "Copy by SQL query" +msgstr "Copy by SQL query" + +msgid "Copy all uncopied jobs (Pool Uncopied Jobs)" +msgstr "Copy all uncopied jobs (Pool Uncopied Jobs)" + +msgid "See backup jobs" +msgstr "See backup jobs" + +msgid "See clients" +msgstr "See clients" + +msgid "See volumes" +msgstr "See volumes" + +msgid "Warning" +msgstr "Warning" + +msgid "Note." +msgstr "Note." + +msgid "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" +msgstr "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" + +msgid "See all jobs that use the pool" +msgstr "See all jobs that use the pool" + +msgid "Step 4 - where you like to copy" +msgstr "Step 4 - where you like to copy" + +msgid "Destination Pool" +msgstr "Destination Pool" + +msgid "Please select destination pool to which will be stored data." +msgstr "Please select destination pool to which will be stored data." + +msgid "Destination Storage" +msgstr "Destination Storage" + +msgid "Step 5 - copy job options" +msgstr "Step 5 - copy job options" + +msgid "Other options" +msgstr "Other options" + +msgid "Pick job name" +msgstr "Pick job name" + +msgid "Pick client name" +msgstr "Pick client name" + +msgid "Pick volume name" +msgstr "Pick volume name" + +msgid "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." +msgstr "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." + +msgid "Source Storage" +msgstr "Source Storage" + +msgid "Please select a storage using which you want to read copy data." +msgstr "Please select a storage using which you want to read copy data." + +msgid "Please select a storage using which you want to write copied data." +msgstr "Please select a storage using which you want to write copied data." + +msgid "Not used" +msgstr "Not used" + +msgid "New backup job wizard" +msgstr "New backup job wizard" + +msgid "This wizard enables you to create in easy way a new backup job." +msgstr "This wizard enables you to create in easy way a new backup job." diff --git a/gui/baculum/protected/Web/Lang/pt/messages.mo b/gui/baculum/protected/Web/Lang/pt/messages.mo index 3703a8f84..f435f5eff 100644 Binary files a/gui/baculum/protected/Web/Lang/pt/messages.mo and b/gui/baculum/protected/Web/Lang/pt/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/pt/messages.po b/gui/baculum/protected/Web/Lang/pt/messages.po index c7107610b..f88be4582 100644 --- a/gui/baculum/protected/Web/Lang/pt/messages.po +++ b/gui/baculum/protected/Web/Lang/pt/messages.po @@ -3470,3 +3470,132 @@ msgstr "Previous error/warning" msgid "Next error/warning" msgstr "Next error/warning" + +msgid "New backup job" +msgstr "New backup job" + +msgid "New copy job" +msgstr "New copy job" + +msgid "Step 1 - basic information about new job" +msgstr "Step 1 - basic information about new job" + +msgid "New copy job wizard" +msgstr "New copy job wizard" + +msgid "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." +msgstr "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." + +msgid "Step 2 - what you want to copy" +msgstr "Step 2 - what you want to copy" + +msgid "Source Pool" +msgstr "Source Pool" + +msgid "Please select a pool from which you want to copy data." +msgstr "Please select a pool from which you want to copy data." + +msgid "The source pool will be examined for finding backup jobs to copy." +msgstr "The source pool will be examined for finding backup jobs to copy." + +msgid "See volumes in selected pool" +msgstr "See volumes in selected pool" + +msgid "Step 3 - how would you like to copy" +msgstr "Step 3 - how would you like to copy" + +msgid "Backup jobs selection criteria" +msgstr "Backup jobs selection criteria" + +msgid "Please select the criteria that will be used for selecting backup jobs to copy." +msgstr "Please select the criteria that will be used for selecting backup jobs to copy." + +msgid "Copy by job" +msgstr "Copy by job" + +msgid "Copy by client" +msgstr "Copy by client" + +msgid "Copy by volume" +msgstr "Copy by volume" + +msgid "Copy by smallest volume" +msgstr "Copy by smallest volume" + +msgid "Copy by oldest volume" +msgstr "Copy by oldest volume" + +msgid "Copy by SQL query" +msgstr "Copy by SQL query" + +msgid "Copy all uncopied jobs (Pool Uncopied Jobs)" +msgstr "Copy all uncopied jobs (Pool Uncopied Jobs)" + +msgid "See backup jobs" +msgstr "See backup jobs" + +msgid "See clients" +msgstr "See clients" + +msgid "See volumes" +msgstr "See volumes" + +msgid "Warning" +msgstr "Warning" + +msgid "Note." +msgstr "Note." + +msgid "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" +msgstr "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" + +msgid "See all jobs that use the pool" +msgstr "See all jobs that use the pool" + +msgid "Step 4 - where you like to copy" +msgstr "Step 4 - where you like to copy" + +msgid "Destination Pool" +msgstr "Destination Pool" + +msgid "Please select destination pool to which will be stored data." +msgstr "Please select destination pool to which will be stored data." + +msgid "Destination Storage" +msgstr "Destination Storage" + +msgid "Step 5 - copy job options" +msgstr "Step 5 - copy job options" + +msgid "Other options" +msgstr "Other options" + +msgid "Pick job name" +msgstr "Pick job name" + +msgid "Pick client name" +msgstr "Pick client name" + +msgid "Pick volume name" +msgstr "Pick volume name" + +msgid "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." +msgstr "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." + +msgid "Source Storage" +msgstr "Source Storage" + +msgid "Please select a storage using which you want to read copy data." +msgstr "Please select a storage using which you want to read copy data." + +msgid "Please select a storage using which you want to write copied data." +msgstr "Please select a storage using which you want to write copied data." + +msgid "Not used" +msgstr "Not used" + +msgid "New backup job wizard" +msgstr "New backup job wizard" + +msgid "This wizard enables you to create in easy way a new backup job." +msgstr "This wizard enables you to create in easy way a new backup job." diff --git a/gui/baculum/protected/Web/Lang/ru/messages.mo b/gui/baculum/protected/Web/Lang/ru/messages.mo index dfba24487..96fb66347 100644 Binary files a/gui/baculum/protected/Web/Lang/ru/messages.mo and b/gui/baculum/protected/Web/Lang/ru/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/ru/messages.po b/gui/baculum/protected/Web/Lang/ru/messages.po index d45b6f5b5..24ab224bb 100644 --- a/gui/baculum/protected/Web/Lang/ru/messages.po +++ b/gui/baculum/protected/Web/Lang/ru/messages.po @@ -3469,3 +3469,132 @@ msgstr "Previous error/warning" msgid "Next error/warning" msgstr "Next error/warning" + +msgid "New backup job" +msgstr "New backup job" + +msgid "New copy job" +msgstr "New copy job" + +msgid "Step 1 - basic information about new job" +msgstr "Step 1 - basic information about new job" + +msgid "New copy job wizard" +msgstr "New copy job wizard" + +msgid "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." +msgstr "Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon." + +msgid "Step 2 - what you want to copy" +msgstr "Step 2 - what you want to copy" + +msgid "Source Pool" +msgstr "Source Pool" + +msgid "Please select a pool from which you want to copy data." +msgstr "Please select a pool from which you want to copy data." + +msgid "The source pool will be examined for finding backup jobs to copy." +msgstr "The source pool will be examined for finding backup jobs to copy." + +msgid "See volumes in selected pool" +msgstr "See volumes in selected pool" + +msgid "Step 3 - how would you like to copy" +msgstr "Step 3 - how would you like to copy" + +msgid "Backup jobs selection criteria" +msgstr "Backup jobs selection criteria" + +msgid "Please select the criteria that will be used for selecting backup jobs to copy." +msgstr "Please select the criteria that will be used for selecting backup jobs to copy." + +msgid "Copy by job" +msgstr "Copy by job" + +msgid "Copy by client" +msgstr "Copy by client" + +msgid "Copy by volume" +msgstr "Copy by volume" + +msgid "Copy by smallest volume" +msgstr "Copy by smallest volume" + +msgid "Copy by oldest volume" +msgstr "Copy by oldest volume" + +msgid "Copy by SQL query" +msgstr "Copy by SQL query" + +msgid "Copy all uncopied jobs (Pool Uncopied Jobs)" +msgstr "Copy all uncopied jobs (Pool Uncopied Jobs)" + +msgid "See backup jobs" +msgstr "See backup jobs" + +msgid "See clients" +msgstr "See clients" + +msgid "See volumes" +msgstr "See volumes" + +msgid "Warning" +msgstr "Warning" + +msgid "Note." +msgstr "Note." + +msgid "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" +msgstr "To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool?" + +msgid "See all jobs that use the pool" +msgstr "See all jobs that use the pool" + +msgid "Step 4 - where you like to copy" +msgstr "Step 4 - where you like to copy" + +msgid "Destination Pool" +msgstr "Destination Pool" + +msgid "Please select destination pool to which will be stored data." +msgstr "Please select destination pool to which will be stored data." + +msgid "Destination Storage" +msgstr "Destination Storage" + +msgid "Step 5 - copy job options" +msgstr "Step 5 - copy job options" + +msgid "Other options" +msgstr "Other options" + +msgid "Pick job name" +msgstr "Pick job name" + +msgid "Pick client name" +msgstr "Pick client name" + +msgid "Pick volume name" +msgstr "Pick volume name" + +msgid "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." +msgstr "Level, Client and FileSet are not used during copy jobs running but they are required to define in copy job resource as the standard Job directives." + +msgid "Source Storage" +msgstr "Source Storage" + +msgid "Please select a storage using which you want to read copy data." +msgstr "Please select a storage using which you want to read copy data." + +msgid "Please select a storage using which you want to write copied data." +msgstr "Please select a storage using which you want to write copied data." + +msgid "Not used" +msgstr "Not used" + +msgid "New backup job wizard" +msgstr "New backup job wizard" + +msgid "This wizard enables you to create in easy way a new backup job." +msgstr "This wizard enables you to create in easy way a new backup job." diff --git a/gui/baculum/protected/Web/Pages/JobHistoryList.page b/gui/baculum/protected/Web/Pages/JobHistoryList.page index 512c749da..6ffe38c7a 100644 --- a/gui/baculum/protected/Web/Pages/JobHistoryList.page +++ b/gui/baculum/protected/Web/Pages/JobHistoryList.page @@ -8,7 +8,8 @@
- + +
- + + + + + +
+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+

<%=$this->Parent->ActiveStep->Title%>

+
+ +
+ +  <%[ Cancel ]%> + + + <%[ Next ]%>  + +
+
+ + +
+ +  <%[ Cancel ]%> + + +  <%[ Previous ]%> + + + <%[ Next ]%>  + +
+
+ +
+ +  <%[ Cancel ]%> + + +  <%[ Previous ]%> + + + <%[ Create job ]%>   + +
+
+ + +
+

<%[ New copy job wizard ]%>

+

<%[ Copy jobs run copying backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. All process runs without using file daemon. ]%>

+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+

<%[ Source Pool ]%>

+

<%[ Please select a pool from which you want to copy data. ]%>

+

<%[ The source pool will be examined for finding backup jobs to copy. ]%>

+
+ +
+

<%[ Source Storage ]%>

+

<%[ Please select a storage using which you want to read copy data. ]%>

+
+
+
+ +
+ + +
+ + + +
+ +
+

<%[ Backup jobs selection criteria ]%>

+

<%[ Please select the criteria that will be used for selecting backup jobs to copy. ]%>

+
+
+
+ +
+
+ + + + + + + + + + + +
+ +
+

<%[ Destination Pool ]%>

+

<%[ Please select destination pool to which will be stored data. ]%>

+
+
+
+ +
+ + + + + +
+
+

<%[ Destination Storage ]%>

+

<%[ Please select a storage using which you want to write copied data. ]%>

+
+
+
+ +
+
+
+ +
+

<%[ Limits ]%>

+
+
+
+ +
+
+
+

<%[ Schedule ]%>

+
+
+
+ +
+
+
+

<%[ Messages ]%>

+
+
+
+ +
+
+ + +
+ +
+ <%[ General ]%> +
+
Job Name
+
<%=$this->Name->getDirectiveValue()%>
+
+
+
Description
+
<%=$this->Description->getDirectiveValue() ?: '-'%>
+
+
+
JobDefs
+
<%=$this->JobDefs->getDirectiveValue() ?: '-'%>
+
+
+
+ <%[ What ]%> +
+
Source Pool
+
+ <%=$this->Pool->getDirectiveValue()%> + <%=$this->isInJobDefs('Pool', $this->Pool->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Source Storage
+
+ <%=$this->SourceStorage->getDirectiveValue()%> + <%=$this->isInJobDefs('Storage', $this->SourceStorage->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
+ <%[ How ]%> +
+
Selection Type
+
+ <%=$this->sel_types[$this->SelectionType->getDirectiveValue()]%> + <%=$this->isInJobDefs('SelectionType', $this->SelectionType->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Selection Pattern
+
+ <%=$this->getPage()->getSelectionPatternValue() ?: '-'%> + <%=$this->isInJobDefs('SelectionPattern', ($this->getSelectionPatternControl() ? $this->getSelectionPatternControl()->getDirectiveValue() : '')) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
+ <%[ Where ]%> +
+
Destination Pool (NextPool)
+
+ <%=$this->NextPool->getDirectiveValue()%> + <%=$this->isInJobDefs('NextPool', $this->Pool->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Destination Storage
+
+ <%=$this->DestinationStorage->getDirectiveValue()%> +
+
+
+
+ <%[ Options ]%> +
+
Maximum Spawned Jobs
+
+ <%=$this->MaximumSpawnedJobs->getDirectiveValue() ?: '-'%> + <%=$this->isInJobDefs('MaximumSpawnedJobs', $this->MaximumSpawnedJobs->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Schedule
+
+ <%=$this->Schedule->getDirectiveValue() ?: '-' %> + <%=$this->isInJobDefs('Schedule', $this->Schedule->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Messages
+
+ <%=$this->Messages->getDirectiveValue() ?: '-'%> + <%=$this->isInJobDefs('Messages', $this->Messages->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Level
+
+ <%=$this->Level->getDirectiveValue() ?: '-'%> + (<%[ Not used ]%>) <%=$this->isInJobDefs('Level', $this->Level->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
Client
+
+ <%=$this->Client->getDirectiveValue()%> + (<%[ Not used ]%>) <%=$this->isInJobDefs('Client', $this->Client->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+
FileSet
+
+ <%=$this->FileSet->getDirectiveValue()%> + (<%[ Not used ]%>) <%=$this->isInJobDefs('Fileset', $this->FileSet->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%> +
+
+
+ +
+ + diff --git a/gui/baculum/protected/Web/Pages/NewCopyJobWizard.php b/gui/baculum/protected/Web/Pages/NewCopyJobWizard.php new file mode 100644 index 000000000..55b4c8829 --- /dev/null +++ b/gui/baculum/protected/Web/Pages/NewCopyJobWizard.php @@ -0,0 +1,764 @@ + + * @category Page + * @package Baculum Web + */ +class NewCopyJobWizard extends BaculumWebPage { + + const PREV_STEP = 'PrevStep'; + const JOBDEFS = 'JobDefs'; + + /** + * Stores available selection types. + * + * @var array + */ + public $sel_types = []; + + public function onInit($param) { + parent::onInit($param); + $this->sel_types = [ + 'Job' => Prado::localize('Copy by job'), + 'Client' => Prado::localize('Copy by client'), + 'Volume' => Prado::localize('Copy by volume'), + 'SmallestVolume' => Prado::localize('Copy by smallest volume'), + 'OldestVolume' => Prado::localize('Copy by oldest volume'), + 'SQLQuery' => Prado::localize('Copy by SQL query'), + 'PoolUncopiedJobs' => Prado::localize('Copy all uncopied jobs (Pool Uncopied Jobs)') + ]; + } + + public function onLoad($param) { + parent::onLoad($param); + $this->JobDefs->saveDirective(); + $this->Pool->saveDirective(); + $this->SelectionType->saveDirective(); + $this->NextPool->saveDirective(); + $this->SourceStorage->saveDirective(); + $this->DestinationStorage->saveDirective(); + $this->Messages->saveDirective(); + $this->Schedule->saveDirective(); + $this->Level->saveDirective(); + $this->Client->saveDirective(); + $this->FileSet->saveDirective(); + } + + public function onLoadComplete($param) { + parent::onLoadComplete($param); + $step_index = $this->NewJobWizard->getActiveStepIndex(); + $prev_step = $this->getPrevStep(); + $this->setPrevStep($step_index); + if ($prev_step > $step_index) { + return; + } + switch ($step_index) { + case 0: { + $this->loadJobDefs(); + break; + } + case 1: { + $this->setupJobDefs(); + $this->loadPools(); + $this->loadSourceStorages(); + break; + } + case 2: { + $this->loadSelectionTypes(); + break; + } + case 3: { + $this->loadNextPools(); + $this->loadDestinationStorages(); + break; + } + case 4: { + $this->loadSchedules(); + $this->loadMessages(); + $this->loadLevels(); + $this->loadClients(); + $this->loadFileSets(); + break; + } + } + } + + /** + * Wizard previous button callback actions. + * + * @param TWizard $sender sender object + * @param TWizardNavigationEventParameter $param sender parameters + * @return none + */ + public function wizardPrev($sender, $param) { + } + + /** + * Wizard next button callback actions. + * + * @param TWizard $sender sender object + * @param TWizardNavigationEventParameter $param sender parameters + * @return none + */ + public function wizardNext($sender, $param) { + } + + /** + * Load JobDefs (step 1). + * + * @return none + */ + public function loadJobDefs() { + $jobdefs_list = []; + $jobdefs = $this->getModule('api')->get([ + 'config', + 'dir', + 'jobdefs'] + ); + if ($jobdefs->error === 0) { + for ($i = 0; $i < count($jobdefs->output); $i++) { + $jobdefs_list[] = $jobdefs->output[$i]->JobDefs->Name; + } + asort($jobdefs_list); + $this->JobDefs->setData($jobdefs_list); + $this->JobDefs->onLoad(null); + } + } + + /** + * Setup and remember selected JobDefs values to use in next wizard steps. + * + * @return none + */ + public function setupJobDefs() { + $directive_value = $this->JobDefs->getDirectiveValue(); + if (is_null($directive_value)) { + return; + } + $jobdefs = $directive_value; + $result = $this->getModule('api')->get([ + 'config', + 'dir', + 'jobdefs', + $jobdefs + ]); + if ($result->error === 0) { + $value = (array)$result->output; + $this->setJobDefs($value); + } + } + + /** + * Check if directive with given value exists in used JobDefs. + * + * @param string $directive_name directive name + * @param string $directive_value directive value + * @return boolean true if directive exists in JobDefs, otherwise false + */ + public function isInJobDefs($directive_name, $directive_value) { + $jobdefs = $this->getJobDefs(); + $ret = false; + if ($directive_name === 'Storage') { + $ret = (key_exists($directive_name, $jobdefs) && $jobdefs[$directive_name][0] === $directive_value); + } else { + $ret = (key_exists($directive_name, $jobdefs) && $jobdefs[$directive_name] === $directive_value); + } + return $ret; + } + + /** + * Set pool type controls (Pool, NextPool ...etc.) + * + * @param string $name pool type directive name + * @param object $control different type of controls (usually DirectiveComboBox) + * @return none + */ + public function setPools($name, $control) { + $pool_list = []; + $pools = $this->getModule('api')->get(['config', 'dir', 'pool'])->output; + for ($i = 0; $i < count($pools); $i++) { + $pool_list[] = $pools[$i]->Pool->Name; + } + asort($pool_list); + $control->setData($pool_list); + $jobdefs = $this->getJobDefs(); + if (key_exists($name, $jobdefs) && is_null($control->getDirectiveValue())) { + $control->setDirectiveValue($jobdefs[$name]); + } + $control->onLoad(null); + } + + /** + * Load pool list (step 2). + * + * @return none + */ + public function loadPools() { + $this->setPools('Pool', $this->Pool); + } + + /** + * Load volumes to display while source pool is configured. + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function loadVolumes($sender, $param) { + $pool = $param->getCallbackParameter(); + $volumes = $this->getVolumes($pool); + $this->getCallbackClient()->callClientFunction( + 'oVolumeList.update', + [$volumes] + ); + } + + /** + * Get volume list for given pool. + * + * @param string $pool pool name + * @return array volume list or empty array on error + */ + public function getVolumes($pool) { + $poolid = null; + $result = $this->getModule('api')->get(['pools']); + if ($result->error === 0) { + for ($i = 0; $i < count($result->output); $i++) { + if ($pool === $result->output[$i]->name) { + $poolid = $result->output[$i]->poolid; + break; + } + } + } + $ret = []; + if ($poolid) { + $result = $this->getModule('api')->get( + ['pools', $poolid, 'volumes'] + ); + if ($result->error === 0) { + $ret = $result->output; + } + } + return $ret; + } + + /** + * Load source storage list (step 2). + * + * @return none + */ + public function loadSourceStorages() { + $this->setStorages($this->SourceStorage); + } + + /** + * Set source storage control basing on pool configuration. + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function setSourceStorageByPool($sender, $param) { + $pool = $this->Pool->getDirectiveValue(); + if (empty($pool)) { + return; + } + $this->setStorageByPool($pool, 'set_storage_from_pool_cb'); + } + + /** + * Load selection types (step 3). + * + * @return none + */ + public function loadSelectionTypes() { + $this->SelectionType->setData($this->sel_types); + $this->SelectionType->onLoad(null); + } + + /** + * Load jobs to select one (step 3). + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function loadJobList($sender, $param) { + $result = $this->getModule('api')->get([ + 'jobs', + 'show', + '?output=json' + ]); + $jobs = []; + if ($result->error === 0) { + for ($i = 0; $i < count($result->output); $i++) { + if ($result->output[$i]->jobtype != '66') { + continue; + } + $jobs[] = [ + 'job' => $result->output[$i]->name, + 'enabled' => $result->output[$i]->enabled, + 'priority' => $result->output[$i]->priority, + 'type' => chr($result->output[$i]->jobtype), + 'maxjobs' => $result->output[$i]->maxjobs + ]; + } + } + $this->getCallbackClient()->callClientFunction( + 'oJobList.init', + [$jobs] + ); + } + + /** + * Load clients to select one (step 3). + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function loadClientList($sender, $param) { + $result = $this->getModule('api')->get( + ['clients'] + ); + $clients = []; + if ($result->error === 0) { + $clients = $result->output; + } + $this->getCallbackClient()->callClientFunction( + 'oClientList.init', + [$clients] + ); + } + + /** + * Load pool list (step 4). + * + * @return none + */ + public function loadNextPools() { + $this->setPools('NextPool', $this->NextPool); + } + + public function setStorages($control) { + $storage_list = []; + $storages = $this->getModule('api')->get([ + 'config', + 'dir', + 'storage' + ]); + if ($storages->error === 0) { + for ($i = 0; $i < count($storages->output); $i++) { + $storage_list[] = $storages->output[$i]->Storage->Name; + } + sort($storage_list); + $control->setData($storage_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Storage', $jobdefs) && is_array($jobdefs['Storage']) && count($jobdefs['Storage']) == 1 && is_null($control->getDirectiveValue())) { + $control->setDirectiveValue($jobdefs['Storage'][0]); + } + $control->onLoad(null); + } + } + + /** + * Load destination storage list (step 4). + * + * @return none + */ + public function loadDestinationStorages() { + $this->setStorages($this->DestinationStorage); + } + + /** + * Set storage control basing on usage in pool. + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function setStorageByPool($pool, $cb) { + $pool = $this->getModule('api')->get([ + 'config', + 'dir', + 'pool', + $pool + ]); + if ($pool->error === 0) { + $storage = null; + if (property_exists($pool->output, 'Storage') && is_array($pool->output->Storage) && count($pool->output->Storage) == 1) { + $storage = $pool->output->Storage[0]; + } + $this->getCallbackClient()->callClientFunction($cb, [$storage]); + } + } + + /** + * Set destination storage control basing on pool configuration. + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function setDestinationStorageByPool($sender, $param) { + $nextpool = $this->NextPool->getDirectiveValue(); + if (empty($nextpool)) { + return; + } + $this->setStorageByPool($nextpool, 'set_storage_from_pool_cb'); + } + + /** + * Get jobs that use pool and send them to warning box. + * + * @param TCallback $sender callback object + * @param TCallbackEventParameter $param callback parameter + * @return none + */ + public function getJobsUsingPool($sender, $param) { + $values = $param->getCallbackParameter(); + $job_list = []; + $jobs = $this->getModule('api')->get([ + 'config', + 'dir', + 'job', + '?apply_jobdefs=1' + ]); + if ($jobs->error === 0) { + for ($i = 0; $i < count($jobs->output); $i++) { + if (property_exists($jobs->output[$i]->Job, 'Pool') && $jobs->output[$i]->Job->Pool == $values->pool) { + $job_list[] = $jobs->output[$i]->Job->Name; + } + } + } + if (count($job_list) > 0) { + sort($job_list); + $this->getCallbackClient()->callClientFunction('show_storage_warning', [ + $values->storage, + $values->pool, + $job_list + ]); + } + } + + /** + * Load messages (step 5). + * + * @return none + */ + public function loadMessages() { + $message_list = []; + $messages = $this->getModule('api')->get([ + 'config', + 'dir', + 'messages' + ]); + if ($messages->error === 0) { + for ($i = 0; $i < count($messages->output); $i++) { + $message_list[] = $messages->output[$i]->Messages->Name; + } + sort($message_list); + $this->Messages->setData($message_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Messages', $jobdefs)) { + $this->Messages->setDirectiveValue($jobdefs['Messages']); + } + $this->Messages->onLoad(null); + } + } + + /** + * Load schedule (step 5). + * + * @return none + */ + public function loadSchedules() { + $schedule_list = []; + $schedules = $this->getModule('api')->get([ + 'config', + 'dir', + 'schedule' + ]); + if ($schedules->error === 0) { + for ($i = 0; $i < count($schedules->output); $i++) { + $schedule_list[] = $schedules->output[$i]->Schedule->Name; + } + asort($schedule_list); + $this->Schedule->setData($schedule_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Schedule', $jobdefs)) { + $this->Schedule->setDirectiveValue($jobdefs['Schedule']); + } + $this->Schedule->onLoad(null); + } + } + + /** + * Load job levels (step 5). + * + * @return none + */ + public function loadLevels() { + // so far backup job levels only + $levels = $this->getModule('misc')->getJobLevels(); + $level_list = array_values($levels); + $this->Level->setData($level_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Level', $jobdefs)) { + $this->Level->setDirectiveValue($jobdefs['Level']); + } elseif (count($level_list) > 0) { + // no level in jobdefs, take first level + $this->Level->setDirectiveValue($level_list[0]); + } + $this->Level->onLoad(null); + } + + /** + * Load clients (step 5). + * + * @return none + */ + public function loadClients() { + $clients = $this->getModule('api')->get([ + 'config', + 'dir', + 'client' + ]); + if ($clients->error === 0) { + for ($i = 0; $i < count($clients->output); $i++) { + $client_list[] = $clients->output[$i]->Client->Name; + } + sort($client_list); + $this->Client->setData($client_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Client', $jobdefs) && is_array($jobdefs['Client']) && is_null($this->Client->getDirectiveValue())) { + $this->Client->setDirectiveValue($jobdefs['Client']); + } elseif (count($client_list) > 0) { + $this->Client->setDirectiveValue($client_list[0]); + } + $this->Client->onLoad(null); + } + } + + /** + * Load filesets (step 5). + * + * @return none + */ + public function loadFileSets() { + $filesets = $this->getModule('api')->get([ + 'config', + 'dir', + 'fileset' + ]); + if ($filesets->error === 0) { + for ($i = 0; $i < count($filesets->output); $i++) { + $fileset_list[] = $filesets->output[$i]->Fileset->Name; + } + sort($fileset_list); + $this->FileSet->setData($fileset_list); + $jobdefs = $this->getJobDefs(); + if (key_exists('Fileset', $jobdefs) && is_array($jobdefs['Fileset']) && is_null($this->Fileset->getDirectiveValue())) { + $this->FileSet->setDirectiveValue($jobdefs['Fileset']); + } elseif (count($fileset_list) > 0) { + $this->FileSet->setDirectiveValue($fileset_list[0]); + } + $this->FileSet->onLoad(null); + } + } + + /** + * Get selection pattern control. + * + * @return DirectiveTextBox selection pattern control. + */ + public function getSelectionPatternControl() { + $control = null; + $sel_type = $this->SelectionType->getDirectiveValue(); + switch ($sel_type) { + case 'Job': $control = $this->SelectionPatternJob; break; + case 'Client': $control = $this->SelectionPatternClient; break; + case 'Volume': $control = $this->SelectionPatternVolume; break; + case 'SQLQuery': $control = $this->SelectionPatternSQLQuery; break; + } + return $control; + } + + /** + * Get selection pattern value. + * + * @return string selection pattern value + */ + public function getSelectionPatternValue() { + $sel_pattern = ''; + $sp_control = $this->getSelectionPatternControl(); + if (is_object($sp_control)) { + $sel_pattern = $sp_control->getDirectiveValue(); + } + return $sel_pattern; + } + + public function wizardCompleted($sender, $param) { + $jobdefs = $this->getJobDefs(); + $job = [ + 'Name' => $this->Name->getDirectiveValue(), + 'Type' => 'Copy', + ]; + $jd = $this->JobDefs->getDirectiveValue(); + $directives = ['Description', 'Pool', 'SourceStorage', 'Level', + 'SelectionType', 'MaximumSpawnedJobs', 'Schedule', + 'Messages', 'Client', 'FileSet', 'NextPool' + ]; + if (is_string($jd)) { + $job['JobDefs'] = $jd; + } + for ($i = 0; $i < count($directives); $i++) { + $val = $this->{$directives[$i]}->getDirectiveValue(); + if (is_null($val)) { + continue; + } + $directive = $directives[$i]; + if ($directive == 'SourceStorage') { + $directive = 'Storage'; + } + if (is_null($jd) || !$this->isInJobDefs($directive, $val)) { + $job[$directive] = $val; + } + } + + // selection type + $sel_type = $this->SelectionType->getDirectiveValue(); + $job['SelectionType'] = $sel_type; + + // selection pattern + $sel_pattern = $this->getSelectionPatternValue(); + if (!empty($sel_pattern)) { + $job['SelectionPattern'] = $sel_pattern; + } + + // Add storage to pool + $nextpool = $this->NextPool->getDirectiveValue(); + $params = [ + 'config', + 'dir', + 'Pool', + $nextpool + ]; + $result = $this->getModule('api')->get( + $params + ); + + $pool_modified = false; + if ($result->error === 0) { + $pool = (array)$result->output; + $pool['Storage'] = $this->DestinationStorage->getDirectiveValue(); + $result = $this->getModule('api')->set( + $params, + ['config' => json_encode($pool)] + ); + if ($result->error === 0) { + $pool_modified = true; + } else { + $this->CreateResourceErrMsg->Display = 'Dynamic'; + $this->CreateResourceErrMsg->Text = $result->output; + } + } + + // create copy job + if ($pool_modified) { + $params = [ + 'config', + 'dir', + 'Job', + $job['Name'] + ]; + $result = $this->getModule('api')->set( + $params, + ['config' => json_encode($job)] + ); + if ($result->error === 0) { + $this->getModule('api')->set(array('console'), array('reload')); + $this->goToPage('JobList'); + } else { + $this->CreateResourceErrMsg->Display = 'Dynamic'; + $this->CreateResourceErrMsg->Text = $result->output; + } + } + } + + /** + * Cancel wizard. + * + * @return none + */ + public function wizardStop($sender, $param) { + $this->goToDefaultPage(); + } + + /** + * Set selected JobDefs values. + * + * @param $jobdefs selected JobDefs values + * @return none + */ + public function setJobDefs($jobdefs) { + $this->setViewState(self::JOBDEFS, $jobdefs); + } + + /** + * Get selected JobDefs values. + * + * @return array selected JobDefs values + */ + public function getJobDefs() { + return $this->getViewState(self::JOBDEFS, array()); + } + + /** + * Set previous wizard step. + * + * @param integer $step previous step number + * @return none + */ + public function setPrevStep($step) { + $step = intval($step); + $this->setViewState(self::PREV_STEP, $step); + } + + /** + * Get previous wizard step. + * + * @return integer previous wizard step + */ + public function getPrevStep() { + return $this->getViewState(self::PREV_STEP); + } +} +?> diff --git a/gui/baculum/protected/Web/endpoints.xml b/gui/baculum/protected/Web/endpoints.xml index 1e218c639..b230d4339 100644 --- a/gui/baculum/protected/Web/endpoints.xml +++ b/gui/baculum/protected/Web/endpoints.xml @@ -39,7 +39,8 @@ - + +