3 * Bacula(R) - The Network Backup Solution
4 * Baculum - Bacula web interface
6 * Copyright (C) 2013-2016 Kern Sibbald
8 * The main author of Baculum is Marcin Haba.
9 * The original author of Bacula is Kern Sibbald, with contributions
10 * from many others, a complete list can be found in the file AUTHORS.
12 * You may use this file and others of this release according to the
13 * license defined in the LICENSE file, which includes the Affero General
14 * Public License, v3.0 ("AGPLv3") and some additional permissions and
15 * terms pursuant to its AGPLv3 Section 7.
17 * This notice must be preserved when any source code is
18 * conveyed and/or propagated.
20 * Bacula(R) is a registered trademark of Kern Sibbald.
23 Prado::using('System.Web.UI.ActiveControls.TActiveHiddenField');
24 Prado::using('System.Web.UI.ActiveControls.TActivePanel');
25 Prado::using('Application.Web.Portlets.Portlets');
27 class JobConfiguration extends Portlets {
29 const USE_CACHE = true;
31 const DEFAULT_JOB_PRIORITY = 10;
33 const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i';
34 const JOB_SHOW_PATTERN = '/^Job:\sname=(?P<jobname>.+)\sJobType=\d+\slevel=(?P<level>\w+)\sPriority=(?P<priority>\d+)/i';
36 public $jobToVerify = array('C', 'O', 'd');
38 public $verifyOptions = array('jobname' => 'Verify by Job Name', 'jobid' => 'Verify by JobId');
40 public function configure($jobId, $params = array()) {
41 $jobdata = $this->Application->getModule('api')->get(array('jobs', $jobId))->output;
42 $this->JobName->Text = $jobdata->job;
43 $this->JobID->Text = $jobdata->jobid;
44 $joblog = $this->Application->getModule('api')->get(array('joblog', $jobdata->jobid))->output;
45 $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates();
46 if (in_array($jobdata->jobstatus, $runningJobStates)) {
47 $this->Estimation->CssClass = 'textbox-auto wheel-loader';
49 $this->Estimation->CssClass = 'textbox-auto';
51 $this->Estimation->Text = is_array($joblog) ? implode(PHP_EOL, $joblog) : Prado::localize("Output for selected job is not available yet or you do not have enabled logging job logs to catalog database. For watching job log there is need to add to the job Messages resource next directive: console = all, !skipped, !saved");
53 $this->Level->dataSource = $this->Application->getModule('misc')->getJobLevels();
54 $this->Level->SelectedValue = $jobdata->level;
55 $this->Level->dataBind();
57 $isVerifyOption = in_array($jobdata->level, $this->jobToVerify);
58 $this->JobToVerifyOptionsLine->Display = ($isVerifyOption === true) ? 'Dynamic' : 'None';
59 $this->JobToVerifyJobNameLine->Display = ($isVerifyOption === true) ? 'Dynamic' : 'None';
60 $this->JobToVerifyJobIdLine->Display = 'None';
61 $this->AccurateLine->Display = ($isVerifyOption === true) ? 'None' : 'Dynamic';
62 $this->EstimateLine->Display = ($isVerifyOption === true) ? 'None' : 'Dynamic';
64 $verifyValues = array();
66 foreach($this->verifyOptions as $value => $text) {
67 $verifyValues[$value] = Prado::localize($text);
70 $this->JobToVerifyOptions->dataSource = $verifyValues;
71 $this->JobToVerifyOptions->dataBind();
73 $jobTasks = $this->Application->getModule('api')->get(array('jobs', 'tasks'), null, true, self::USE_CACHE)->output;
74 $jobsAllDirs = array();
75 foreach($jobTasks as $director => $tasks) {
76 $jobsAllDirs = array_merge($jobsAllDirs, $tasks);
79 $this->JobToVerifyJobName->dataSource = array_combine($jobsAllDirs, $jobsAllDirs);
80 $this->JobToVerifyJobName->dataBind();
82 $clients = $this->Application->getModule('api')->get(array('clients'), null, true, self::USE_CACHE)->output;
83 $clientsList = array();
84 foreach($clients as $client) {
85 $clientsList[$client->clientid] = $client->name;
87 $this->Client->dataSource = $clientsList;
88 $this->Client->SelectedValue = $jobdata->clientid;
89 $this->Client->dataBind();
91 $filesetsAll = $this->Application->getModule('api')->get(array('filesets'), null, true, self::USE_CACHE)->output;
92 $filesetsList = array();
93 foreach($filesetsAll as $director => $filesets) {
94 $filesetsList = array_merge($filesets, $filesetsList);
96 $selectedFileset = '';
97 if($jobdata->filesetid != 0) {
98 $selectedFileset = $this->Application->getModule('api')->get(array('filesets', $jobdata->filesetid), null, true, self::USE_CACHE)->output->fileset;
100 $this->FileSet->dataSource = array_combine($filesetsList, $filesetsList);
101 $this->FileSet->SelectedValue = array_key_exists('fileset', $params) ? $params['fileset'] : $selectedFileset;
102 $this->FileSet->dataBind();
104 $pools = $this->Application->getModule('api')->get(array('pools'), null, true, self::USE_CACHE)->output;
106 foreach($pools as $pool) {
107 $poolList[$pool->poolid] = $pool->name;
109 $this->Pool->dataSource = $poolList;
110 $this->Pool->SelectedValue = array_key_exists('poolid', $params) ? $params['poolid'] : $jobdata->poolid;
111 $this->Pool->dataBind();
113 $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid), null, true, self::USE_CACHE)->output;
114 $storageShow = $this->getResourceName('storage', $jobshow);
115 $storagesList = array();
116 $selectedStorageId = null;
117 $storages = $this->Application->getModule('api')->get(array('storages'), null, true, self::USE_CACHE)->output;
118 foreach($storages as $storage) {
119 if ($storage->name == $storageShow) {
120 $selectedStorageId = $storage->storageid;
122 $storagesList[$storage->storageid] = $storage->name;
124 $this->Storage->dataSource = $storagesList;
125 if (!is_null($selectedStorageId)) {
126 $this->Storage->SelectedValue = $selectedStorageId;
128 $this->Storage->dataBind();
130 $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates();
131 $isJobRunning = in_array($jobdata->jobstatus, $runningJobStates);
133 $this->Priority->Text = ($jobdata->priorjobid == 0) ? self::DEFAULT_JOB_PRIORITY : $jobdata->priorjobid;
134 $this->DeleteButton->Visible = true;
135 $this->CancelButton->Visible = $isJobRunning;
136 $this->RefreshStart->Value = $isJobRunning;
137 $this->Run->Display = 'Dynamic';
138 $this->EstimateLine->Display = 'Dynamic';
139 $this->Status->Visible = true;
142 public function status($sender, $param) {
143 $jobdata = $this->Application->getModule('api')->get(array('jobs', $this->JobID->Text))->output;
144 $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates();
145 if (in_array($jobdata->jobstatus, $runningJobStates)) {
146 $this->RefreshStart->Value = true;
148 $this->RefreshStart->Value = false;
149 $this->CancelButton->Visible = false;
150 $this->Estimation->CssClass = 'textbox-auto';
153 $joblog = $this->Application->getModule('api')->get(array('joblog', $this->JobID->Text))->output;
154 $this->Estimation->Text = is_array($joblog) ? implode(PHP_EOL, $joblog) : Prado::localize("Output for selected job is not available yet or you do not have enabled logging job logs to catalog database. For watching job log there is need to add to the job Messages resource next directive: console = all, !skipped, !saved");
157 public function delete($sender, $param) {
158 $this->Application->getModule('api')->remove(array('jobs', $this->JobID->Text));
159 $this->Status->Visible = false;
160 $this->Run->Display = 'None';
161 $this->DeleteButton->Visible = false;
162 $this->EstimateLine->Display = 'None';
163 $this->Estimation->CssClass = 'textbox-auto';
166 public function cancel($sender, $param) {
167 $this->Application->getModule('api')->set(array('jobs', 'cancel', $this->JobID->Text), array('a' => 'b'));
168 $this->CancelButton->Visible = false;
169 $this->status(null, null);
170 $this->Estimation->CssClass = 'textbox-auto';
173 public function run_again($sender, $param) {
174 if($this->PriorityValidator->IsValid === false) {
179 if (is_null($sender) && is_numeric($param)) {
180 $jobdata = $this->Application->getModule('api')->get(array('jobs', $param))->output;
181 $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid))->output;
182 $params['id'] = $jobdata->jobid;
183 $params['level'] = $jobdata->level;
184 $params['fileset'] = $this->getResourceName('fileset', $jobshow);
185 $params['clientid'] = $jobdata->clientid;
186 $storage = $this->getResourceName('storage', $jobshow);
187 if (!is_null($storage)) {
188 $params['storageid'] = $this->getStorageByName($storage)->storageid;
190 $autochanger = $this->getResourceName('autochanger', $jobshow);
191 if (!is_null($autochanger)) {
192 $params['storageid'] = $this->getStorageByName($autochanger)->storageid;
195 $pool = $this->getResourceName('pool', $jobshow);
196 if (!is_null($pool)) {
197 $params['poolid'] = $this->getPoolByName($pool)->poolid;
200 $params['id'] = $this->JobID->Text;
201 $params['level'] = $this->Level->SelectedValue;
202 $params['fileset'] = $this->FileSet->SelectedValue;
203 $params['clientid'] = $this->Client->SelectedValue;
204 $params['storageid'] = $this->Storage->SelectedValue;
205 $params['poolid'] = $this->Pool->SelectedValue;
206 $params['priority'] = $this->Priority->Text;
208 if (in_array($this->Level->SelectedItem->Value, $this->jobToVerify)) {
209 $verifyVals = $this->getVerifyVals();
210 if ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobname']) {
211 $params['verifyjob'] = $this->JobToVerifyJobName->SelectedValue;
212 } elseif ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) {
213 $params['jobid'] = $this->JobToVerifyJobId->Text;
217 $result = $this->Application->getModule('api')->create(array('jobs', 'run'), $params)->output;
218 $startedJobId = $this->Application->getModule('misc')->findJobIdStartedJob($result);
219 if (is_numeric($startedJobId)) {
220 $params['jobid'] = $startedJobId;
221 $this->configure($startedJobId, $params);
223 $this->Estimation->Text = implode(PHP_EOL, $result);
227 public function estimate($sender, $param) {
229 $params['id'] = $this->JobID->Text;
230 $params['level'] = $this->Level->SelectedValue;
231 $params['fileset'] = $this->FileSet->SelectedValue;
232 $params['clientid'] = $this->Client->SelectedValue;
233 $params['accurate'] = (integer)$this->Accurate->Checked;
234 $result = $this->Application->getModule('api')->create(array('jobs', 'estimate'), $params)->output;
235 $this->Estimation->Text = implode(PHP_EOL, $result);
238 public function priorityValidator($sender, $param) {
239 $isValid = preg_match('/^[0-9]+$/',$this->Priority->Text) === 1 && $this->Priority->Text > 0;
240 $param->setIsValid($isValid);
243 public function jobIdToVerifyValidator($sender, $param) {
244 $verifyVals = $this->getVerifyVals();
245 if(in_array($this->Level->SelectedValue, $this->jobToVerify) && $this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) {
246 $isValid = preg_match('/^[0-9]+$/',$this->JobToVerifyJobId->Text) === 1 && $this->JobToVerifyJobId->Text > 0;
250 $param->setIsValid($isValid);
254 private function getVerifyVals() {
255 $verifyOpt = array_keys($this->verifyOptions);
256 $verifyVals = array_combine($verifyOpt, $verifyOpt);
260 public function getResourceName($resource, $jobshow) {
261 $resource_name = null;
262 $pattern = str_replace('%resource', $resource, self::RESOURCE_SHOW_PATTERN);
263 for ($i = 0; $i < count($jobshow); $i++) {
264 if (preg_match($pattern, $jobshow[$i], $match) === 1) {
265 $resource_name = $match[1];
269 return $resource_name;
272 public function getJobAttr($jobshow) {
274 for ($i = 0; $i < count($jobshow); $i++) {
275 if (preg_match(self::JOB_SHOW_PATTERN, $jobshow[$i], $match) === 1) {
276 $attr['jobname'] = $match['jobname'];
277 $attr['level'] = $match['level'];
278 $attr['priority'] = $match['priority'];
285 private function getPoolByName($name) {
287 $pools = $this->Application->getModule('api')->get(array('pools'), null, true, self::USE_CACHE)->output;
288 for ($i = 0; $i < count($pools); $i++) {
289 if ($pools[$i]->name == $name) {
297 private function getStorageByName($name) {
299 $storages = $this->Application->getModule('api')->get(array('storages'), null, true, self::USE_CACHE)->output;
300 for ($i = 0; $i < count($storages); $i++) {
301 if ($storages[$i]->name == $name) {
302 $storage = $storages[$i];