6 Bweb - A Bacula web interface
7 Bacula® - The Network Backup Solution
9 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
11 The main author of Bweb is Eric Bollengier.
12 The main author of Bacula is Kern Sibbald, with contributions from
13 many others, a complete list can be found in the file AUTHORS.
14 This program is Free Software; you can redistribute it and/or
15 modify it under the terms of version three of the GNU Affero General Public
16 License as published by the Free Software Foundation and included
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU Affero General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 Bacula® is a registered trademark of Kern Sibbald.
30 The licensor of Bacula is the Free Software Foundation Europe
31 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
32 Switzerland, email:ftf@fsfeurope.org.
44 my $client_re = qr/^([\w\d\.-]+)$/;
46 my $action = CGI::param('action') || 'begin';
48 if ($action eq 'restore') {
49 print CGI::header('text/brestore'); # specialy to run brestore.pl
52 print CGI::header('text/html');
56 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
59 my $bweb = new Bweb(info => $conf);
61 # just send data with text/brestore content
62 if ($action eq 'restore') {
67 my $arg = $bweb->get_form('jobid', 'limit', 'offset', 'age');
69 $bweb->display_begin();
71 # if no configuration, we send edit_conf
72 if ($action ne 'apply_conf' and !$bweb->{info}->{dbi}) {
73 $action = 'edit_conf';
76 if ($action eq 'begin') { # main display
77 print "<div style='left=0;'><table border='0'><tr><td valign='top' width='100%'>\n";
78 $bweb->display_general(age => $arg->{age});
79 $bweb->display_running_jobs(0);
80 print "</td><td valign='top'>";
81 $bweb->display({}, "stats.tpl");
82 print "</td></tr></table></div>";
83 $bweb->display_job(limit => 10);
85 } elsif ($action eq 'view_conf') {
86 $bweb->can_do('r_configure');
89 } elsif ($action eq 'edit_conf') {
90 $bweb->can_do('r_configure');
93 } elsif ($action eq 'apply_conf') {
94 $bweb->can_do('r_configure');
97 } elsif ($action eq 'user_del') {
100 } elsif ($action eq 'user_add') {
103 } elsif ($action eq 'user_edit') {
104 $bweb->display_user();
106 } elsif ($action eq 'user_save') {
109 } elsif ($action eq 'users') {
110 $bweb->display_users();
112 } elsif ($action eq 'client') {
113 $bweb->display_clients();
115 } elsif ($action eq 'client_edit') {
116 $bweb->client_edit();
118 } elsif ($action eq 'client_save') {
119 $bweb->client_save();
121 } elsif ($action eq 'pool') {
122 $bweb->display_pool();
124 } elsif ($action eq 'location_edit') {
125 $bweb->location_edit();
127 } elsif ($action eq 'location_save') {
128 $bweb->location_save();
130 } elsif ($action eq 'location_add') {
131 $bweb->location_add();
133 } elsif ($action eq 'location_del') {
134 $bweb->location_del();
136 } elsif ($action eq 'cmd_storage') {
137 $bweb->cmd_storage();
139 } elsif ($action eq 'media') {
140 $bweb->can_do('r_view_media');
142 print "<div><table border='0'><tr><td valign='top'>\n";
143 my $fields = $bweb->get_form(qw/db_locations db_pools expired
144 qlocations qpools volstatus qre_media
145 limit qmediatypes db_mediatypes/);
146 $bweb->display($fields, "display_form_media.tpl");
148 print "</td><td valign='top'>";
149 $bweb->display_media(offset => $arg->{offset},
150 limit => $arg->{limit});
151 print "</td></tr></table></div>";
153 } elsif ($action eq 'allmedia') {
154 $bweb->display_allmedia();
156 } elsif ($action eq 'eject') {
157 $bweb->can_do('r_autochanger_mgnt');
159 my $arg = $bweb->get_form("ach");
160 my $a = $bweb->ach_get($arg->{ach});
164 foreach my $slot (CGI::param('slot')) {
165 print $a->{error} unless $a->send_to_io($slot);
168 foreach my $media (CGI::param('media')) {
169 my $slot = $a->get_media_slot($media);
170 print $a->{error} unless $a->send_to_io($slot);
173 $a->display_content();
175 } elsif ($action eq 'add_media') {
178 } elsif ($action eq 'eject_media') {
179 $bweb->eject_media();
181 } elsif ($action eq 'clear_io') {
182 $bweb->can_do('r_autochanger_mgnt');
184 my $arg = $bweb->get_form('ach');
186 my $a = $bweb->ach_get($arg->{ach});
190 $a->display_content();
193 } elsif ($action eq 'ach_edit') {
196 } elsif ($action eq 'ach_del') {
199 } elsif ($action eq 'ach_view') {
200 $bweb->can_do('r_autochanger_mgnt');
202 # TODO : get autochanger name and create it
204 my $arg = $bweb->get_form('ach');
206 my $a = $bweb->ach_get($arg->{ach});
209 $a->display_content();
212 } elsif ($action eq 'ach_add') {
215 } elsif ($action eq 'ach_load') {
216 $bweb->can_do('r_autochanger_mgnt');
218 my $arg = $bweb->get_form('ach', 'drive', 'slot');
220 my $a = $bweb->ach_get($arg->{ach});
222 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
224 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
225 # TODO : use template here
227 $b->send_cmd("mount slot=$arg->{slot} drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
230 $bweb->error("Can't get drive, slot or ach");
233 } elsif ($action eq 'ach_unload') {
234 $bweb->can_do('r_autochanger_mgnt');
236 my $arg = $bweb->get_form('drive', 'slot', 'ach');
238 my $a = $bweb->ach_get($arg->{ach});
240 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
242 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
243 # TODO : use template here
245 $b->send_cmd("umount drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
249 $bweb->error("Can't get drive, slot or ach");
251 } elsif ($action eq 'intern_media') {
252 $bweb->help_intern();
254 } elsif ($action eq 'compute_intern_media') {
255 $bweb->help_intern_compute();
257 } elsif ($action eq 'extern_media') {
258 $bweb->help_extern();
260 } elsif ($action eq 'compute_extern_media') {
261 $bweb->help_extern_compute();
263 } elsif ($action eq 'extern') {
264 $bweb->can_do('r_media_mgnt');
265 $bweb->can_do('r_autochanger_mgnt');
267 print "<div style='float: left;'>";
268 my @achs = $bweb->eject_media();
269 for my $ach (@achs) {
270 CGI::param('ach', $ach);
271 $bweb->update_slots();
273 print "</div><div style='float: left;margin-left: 20px;'>";
274 $bweb->move_media('yes'); # pb with enabled = no for restore
277 } elsif ($action eq 'move_email') {
280 } elsif ($action eq 'change_location') {
281 $bweb->location_change();
283 } elsif ($action eq 'location') {
284 $bweb->location_display();
286 } elsif ($action eq 'about') {
287 $bweb->display($bweb, 'about.tpl');
289 } elsif ($action eq 'intern') {
290 $bweb->move_media('yes'); # TODO : remove that
292 } elsif ($action eq 'move_media') {
293 my $a = $bweb->get_form('enabled');
294 $bweb->move_media($a->{enabled});
296 } elsif ($action eq 'save_location') {
297 $bweb->save_location();
299 } elsif ($action eq 'update_location') {
300 $bweb->update_location();
302 } elsif ($action eq 'update_media') {
303 $bweb->update_media();
305 } elsif ($action eq 'do_update_media') {
306 $bweb->do_update_media();
308 } elsif ($action eq 'update_slots') {
309 $bweb->update_slots();
311 } elsif ($action eq 'graph') {
312 $bweb->display_graph();
314 } elsif ($action eq 'next_job') {
315 $bweb->director_show_sched();
317 } elsif ($action eq 'enable_job') {
318 $bweb->enable_disable_job(1);
320 } elsif ($action eq 'disable_job') {
321 $bweb->enable_disable_job(0);
323 } elsif ($action eq 'groups') {
324 $bweb->display_groups();
326 } elsif ($action eq 'groups_edit') {
327 $bweb->groups_edit();
329 } elsif ($action eq 'groups_save') {
330 $bweb->groups_save();
332 } elsif ($action eq 'groups_del') {
335 } elsif ($action eq 'job') {
336 $bweb->can_do('r_view_job');
337 print "<div><table border='0'><tr><td valign='top'>\n";
338 my $fields = $bweb->get_form(qw/status level filter db_clients
340 limit age offset qclients qfilesets
341 jobtype qpools db_pools
342 db_client_groups qclient_groups/); # drop this to hide
343 if (!CGI::param('since')) {
344 $fields->{hide_since}=1 ;
345 delete $fields->{since};
347 $bweb->display($fields, "display_form_job.tpl");
349 print "</td><td valign='top'>";
350 $bweb->display_job(age => $fields->{age}, # last 7 days
351 since => $fields->{since},
352 offset => $fields->{offset},
353 limit => $fields->{limit});
354 print "</td></tr></table></div>";
355 } elsif ($action eq 'job_group') {
356 $bweb->can_do('r_view_job');
357 print "<div><table border='0'><tr><td valign='top'>\n";
358 my $fields = $bweb->get_form(qw/limit level age filter
359 db_client_groups qclient_groups/); # drop this to hide
361 $fields->{hide_status} = 1;
362 $fields->{hide_type} = 1;
363 $fields->{hide_since}=1;
364 $fields->{action} = 'job_group';
366 $bweb->display($fields, "display_form_job.tpl");
368 print "</td><td valign='top'>";
369 $bweb->display_job_group(age => $arg->{age}, # last 7 days
370 limit => $arg->{limit});
371 print "</td></tr></table></div>";
372 } elsif ($action eq 'client_stats') {
374 foreach my $client (CGI::param('client')) {
375 if ($client =~ $client_re) {
376 $bweb->display_client_stats(clientname => $1,
380 } elsif ($action eq 'group_stats') {
381 $bweb->can_do('r_view_stat');
382 print "<div><table border='0'><tr><td valign='top'>\n";
383 my $fields = $bweb->get_form(qw/since age
384 db_client_groups qclient_groups/);
385 $fields->{action}='group_stats';
386 $fields->{hide_level}=1;
387 $fields->{hide_type}=1;
388 $fields->{hide_status}=1;
390 $bweb->display($fields, "display_form_job.tpl");
392 print "</td><td valign='top'>";
393 $bweb->display_group_stats();
395 print "</td></tr></table></div>"
397 } elsif ($action eq 'running') {
398 $bweb->display_running_jobs(1);
400 } elsif ($action eq 'dsp_cur_job') {
401 $bweb->display_running_job();
403 } elsif ($action eq 'update_from_pool') {
404 $bweb->can_do('r_media_mgnt');
405 my $elt = $bweb->get_form(qw/media pool/);
406 unless ($elt->{media} || $elt->{pool}) {
407 $bweb->error("Can't get media or pool param");
409 my $b = new Bconsole(pref => $conf) ;
412 content => $b->send_cmd("update volume=$elt->{media} fromPool=$elt->{pool}"),
413 title => "Update pool",
414 name => "update volume=$elt->{media} fromPool=$elt->{pool}",
418 $bweb->update_media();
420 } elsif ($action eq 'client_status') {
421 $bweb->can_do('r_client_status');
423 foreach my $client (CGI::param('client')) {
424 if ($client =~ $client_re) {
426 $b = new Bconsole(pref => $conf)
430 content => $b->send_cmd("st client=$client"),
431 title => "Client status",
436 $bweb->error("Can't get client selection");
440 } elsif ($action eq 'cancel_job') {
443 } elsif ($action eq 'cancel_future_job') {
444 $bweb->cancel_future_job();
446 } elsif ($action eq 'media_zoom') {
447 $bweb->display_media_zoom();
449 } elsif ($action eq 'job_zoom') {
451 $bweb->display_job_zoom($arg->{jobid});
452 $bweb->get_job_log();
454 } elsif ($action eq 'job_log') {
455 $bweb->get_job_log();
457 } elsif ($action eq 'prune') {
460 } elsif ($action eq 'purge') {
463 } elsif ($action eq 'run_job') {
466 } elsif ($action eq 'run_job_mod') {
467 $bweb->run_job_mod();
469 } elsif ($action eq 'run_job_now') {
470 $bweb->run_job_now();
472 } elsif ($action eq 'label_barcodes') {
473 $bweb->label_barcodes();
475 } elsif ($action eq 'delete') {
478 } elsif ($action eq 'fileset_view') {
479 $bweb->fileset_view();
481 } elsif ($action eq 'next_job2') {
482 $bweb->display_next_job();
484 } elsif ($action eq 'missing') {
485 $bweb->display_missing_job();
487 } elsif ($action eq 'overview') {
488 $bweb->can_do('r_view_job');
489 print "<div><table border='0'><tr><td valign='top'>\n";
490 my $fields = $bweb->get_form(qw/level filter age jobtype since type
491 db_client_groups qclient_groups/); # drop this to hide
492 $fields->{hide_status}=1;
493 $fields->{view_time_slice}=1;
494 $fields->{action}='overview';
495 $bweb->display($fields, "display_form_job.tpl");
497 print "</td><td valign='top'>";
498 $bweb->display_overview();
499 print "</td></tr></table></div>";
501 } elsif ($action eq 'overview_zoom') {
502 $bweb->can_do('r_view_job');
503 print "<div><table border='0'><tr><td valign='top'>\n";
504 my $fields = $bweb->get_form(qw/level filter age jobtype since type
505 db_client_groups qclient_groups/); # drop this to hide
506 $fields->{hide_status}=1;
507 $fields->{view_time_slice}=1;
508 $fields->{action}='overview_zoom';
509 $bweb->display($fields, "display_form_job.tpl");
510 print "</td><td valign='top'>";
511 $bweb->display_overview_zoom();
512 print "</td></tr></table></div>";
515 $bweb->error("Sorry, this action doesn't exist");
518 $bweb->display_end();
520 $bweb->dbh_disconnect();
526 o Affichage des medias qui ont besoin d'etre change
527 o Affichage des infos de query.sql
529 - Affichage des du TapeAlert sur le site
530 - Recuperation des erreurs SCSI de /var/log/kern.log