6 Bweb - A Bacula web interface
7 Bacula® - The Network Backup Solution
9 Copyright (C) 2006-2010 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 Affero 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.
40 my $client_re = qr/^([\w\d\.-]+)$/;
42 my $action = CGI::param('action') || 'begin';
44 if ($action eq 'restore') {
45 print CGI::header('text/brestore'); # specialy to run brestore.pl
48 print CGI::header('text/html');
52 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
55 my $bweb = new Bweb(info => $conf);
57 # just send data with text/brestore content
58 if ($action eq 'restore') {
63 my $arg = $bweb->get_form('jobid', 'limit', 'offset', 'age');
65 $bweb->display_begin();
67 # if no configuration, we send edit_conf
68 if ($action ne 'apply_conf' and !$bweb->{info}->{dbi}) {
69 $action = 'edit_conf';
72 if ($action eq 'begin') { # main display
73 print "<div style='left=0;'><table border='0'><tr><td valign='top' width='100%'>\n";
74 $bweb->display_general(age => $arg->{age});
75 $bweb->display_running_jobs(0);
76 print "</td><td valign='top'>";
77 $bweb->display({}, "stats.tpl");
78 print "</td></tr></table></div>";
79 $bweb->display_job(limit => 10);
81 } elsif ($action eq 'view_conf') {
82 $bweb->can_do('r_configure');
85 } elsif ($action eq 'edit_conf') {
86 $bweb->can_do('r_configure');
89 } elsif ($action eq 'apply_conf') {
90 $bweb->can_do('r_configure');
93 } elsif ($action eq 'user_del') {
96 } elsif ($action eq 'user_add') {
99 } elsif ($action eq 'user_edit') {
100 $bweb->display_user();
102 } elsif ($action eq 'user_save') {
105 } elsif ($action eq 'users') {
106 $bweb->display_users();
108 } elsif ($action eq 'client') {
109 $bweb->display_clients();
111 } elsif ($action eq 'client_edit') {
112 $bweb->client_edit();
114 } elsif ($action eq 'client_save') {
115 $bweb->client_save();
117 } elsif ($action eq 'pool') {
118 $bweb->display_pool();
120 } elsif ($action eq 'location_edit') {
121 $bweb->location_edit();
123 } elsif ($action eq 'location_save') {
124 $bweb->location_save();
126 } elsif ($action eq 'location_add') {
127 $bweb->location_add();
129 } elsif ($action eq 'location_del') {
130 $bweb->location_del();
132 } elsif ($action eq 'cmd_storage') {
133 $bweb->cmd_storage();
135 } elsif ($action eq 'list_files') {
136 $bweb->display_files();
138 } elsif ($action eq 'media') {
139 $bweb->can_do('r_view_media');
141 print "<div><table border='0'><tr><td valign='top'>\n";
142 my $fields = $bweb->get_form(qw/db_locations db_pools expired
143 qlocations qpools volstatus qre_media
144 limit qmediatypes db_mediatypes/);
145 $bweb->display($fields, "display_form_media.tpl");
147 print "</td><td valign='top'>";
148 $bweb->display_media(offset => $arg->{offset},
149 limit => $arg->{limit});
150 print "</td></tr></table></div>";
152 } elsif ($action eq 'allmedia') {
153 $bweb->display_allmedia();
155 } elsif ($action eq 'eject') {
156 $bweb->can_do('r_autochanger_mgnt');
158 my $arg = $bweb->get_form("ach");
159 my $a = $bweb->ach_get($arg->{ach});
163 foreach my $slot (CGI::param('slot')) {
164 print $a->{error} unless $a->send_to_io($slot);
167 foreach my $media (CGI::param('media')) {
168 my $slot = $a->get_media_slot($media);
169 print $a->{error} unless $a->send_to_io($slot);
172 $a->display_content();
174 } elsif ($action eq 'add_media') {
177 } elsif ($action eq 'eject_media') {
178 $bweb->eject_media();
180 } elsif ($action eq 'clear_io') {
181 $bweb->can_do('r_autochanger_mgnt');
183 my $arg = $bweb->get_form('ach');
185 my $a = $bweb->ach_get($arg->{ach});
189 $a->display_content();
192 } elsif ($action eq 'ach_edit') {
195 } elsif ($action eq 'ach_del') {
198 } elsif ($action eq 'ach_view') {
199 $bweb->can_do('r_autochanger_mgnt');
201 # TODO : get autochanger name and create it
203 my $arg = $bweb->get_form('ach');
205 my $a = $bweb->ach_get($arg->{ach});
208 $a->display_content();
211 } elsif ($action eq 'ach_add') {
214 } elsif ($action eq 'ach_load') {
215 $bweb->can_do('r_autochanger_mgnt');
217 my $arg = $bweb->get_form('ach', 'drive', 'slot');
219 my $a = $bweb->ach_get($arg->{ach});
221 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
223 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
224 # TODO : use template here
226 $b->send_cmd("mount slot=$arg->{slot} drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
229 $bweb->error("Can't get drive, slot or ach");
232 } elsif ($action eq 'ach_unload') {
233 $bweb->can_do('r_autochanger_mgnt');
235 my $arg = $bweb->get_form('drive', 'slot', 'ach');
237 my $a = $bweb->ach_get($arg->{ach});
239 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
241 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
242 # TODO : use template here
244 $b->send_cmd("umount drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
248 $bweb->error("Can't get drive, slot or ach");
250 } elsif ($action eq 'intern_media') {
251 $bweb->help_intern();
253 } elsif ($action eq 'compute_intern_media') {
254 $bweb->help_intern_compute();
256 } elsif ($action eq 'extern_media') {
257 $bweb->help_extern();
259 } elsif ($action eq 'compute_extern_media') {
260 $bweb->help_extern_compute();
262 } elsif ($action eq 'extern') {
263 $bweb->can_do('r_media_mgnt');
264 $bweb->can_do('r_autochanger_mgnt');
266 print "<div style='float: left;'>";
267 my @achs = $bweb->eject_media();
268 for my $ach (@achs) {
269 CGI::param('ach', $ach);
270 $bweb->update_slots();
272 print "</div><div style='float: left;margin-left: 20px;'>";
273 $bweb->move_media('yes'); # pb with enabled = no for restore
276 } elsif ($action eq 'move_email') {
279 } elsif ($action eq 'change_location') {
280 $bweb->location_change();
282 } elsif ($action eq 'location') {
283 $bweb->location_display();
285 } elsif ($action eq 'about') {
286 $bweb->display($bweb, 'about.tpl');
288 } elsif ($action eq 'intern') {
289 $bweb->move_media('yes'); # TODO : remove that
291 } elsif ($action eq 'move_media') {
292 my $a = $bweb->get_form('enabled');
293 $bweb->move_media($a->{enabled});
295 } elsif ($action eq 'save_location') {
296 $bweb->save_location();
298 } elsif ($action eq 'update_location') {
299 $bweb->update_location();
301 } elsif ($action eq 'update_media') {
302 $bweb->update_media();
304 } elsif ($action eq 'do_update_media') {
305 $bweb->do_update_media();
307 } elsif ($action eq 'update_slots') {
308 $bweb->update_slots();
310 } elsif ($action eq 'graph') {
311 $bweb->display_graph();
313 } elsif ($action eq 'next_job') {
314 $bweb->director_show_sched();
316 } elsif ($action eq 'enable_job') {
317 $bweb->enable_disable_job(1);
319 } elsif ($action eq 'disable_job') {
320 $bweb->enable_disable_job(0);
322 } elsif ($action eq 'groups') {
323 $bweb->display_groups();
325 } elsif ($action eq 'groups_edit') {
326 $bweb->groups_edit();
328 } elsif ($action eq 'groups_save') {
329 $bweb->groups_save();
331 } elsif ($action eq 'groups_del') {
334 } elsif ($action eq 'job') {
335 $bweb->can_do('r_view_job');
336 print "<div><table border='0'><tr><td valign='top'>\n";
337 my $fields = $bweb->get_form(qw/status level filter db_clients
339 limit age offset qclients qfilesets
340 jobtype qpools db_pools
341 db_client_groups qclient_groups/); # drop this to hide
342 if (!CGI::param('since')) {
343 $fields->{hide_since}=1 ;
344 delete $fields->{since};
346 $bweb->display($fields, "display_form_job.tpl");
348 print "</td><td valign='top'>";
349 $bweb->display_job(age => $fields->{age}, # last 7 days
350 since => $fields->{since},
351 offset => $fields->{offset},
352 limit => $fields->{limit});
353 print "</td></tr></table></div>";
354 } elsif ($action eq 'job_group') {
355 $bweb->can_do('r_view_job');
356 print "<div><table border='0'><tr><td valign='top'>\n";
357 my $fields = $bweb->get_form(qw/limit level age filter
358 db_client_groups qclient_groups/); # drop this to hide
360 $fields->{hide_status} = 1;
361 $fields->{hide_type} = 1;
362 $fields->{hide_since}=1;
363 $fields->{action} = 'job_group';
365 $bweb->display($fields, "display_form_job.tpl");
367 print "</td><td valign='top'>";
368 $bweb->display_job_group(age => $arg->{age}, # last 7 days
369 limit => $arg->{limit});
370 print "</td></tr></table></div>";
371 } elsif ($action eq 'client_stats') {
373 foreach my $client (CGI::param('client')) {
374 if ($client =~ $client_re) {
375 $bweb->display_client_stats(clientname => $1,
379 } elsif ($action eq 'group_stats') {
380 $bweb->can_do('r_view_stat');
381 print "<div><table border='0'><tr><td valign='top'>\n";
382 my $fields = $bweb->get_form(qw/since age
383 db_client_groups qclient_groups/);
384 $fields->{action}='group_stats';
385 $fields->{hide_level}=1;
386 $fields->{hide_type}=1;
387 $fields->{hide_status}=1;
389 $bweb->display($fields, "display_form_job.tpl");
391 print "</td><td valign='top'>";
392 $bweb->display_group_stats();
394 print "</td></tr></table></div>"
396 } elsif ($action eq 'running') {
397 $bweb->display_running_jobs(1);
399 } elsif ($action eq 'dsp_cur_job') {
400 $bweb->display_running_job();
402 } elsif ($action eq 'update_from_pool') {
403 $bweb->can_do('r_media_mgnt');
404 my $elt = $bweb->get_form(qw/media pool/);
405 unless ($elt->{media} || $elt->{pool}) {
406 $bweb->error("Can't get media or pool param");
408 my $b = new Bconsole(pref => $conf) ;
411 content => $b->send_cmd("update volume=$elt->{media} fromPool=$elt->{pool}"),
412 title => "Update pool",
413 name => "update volume=$elt->{media} fromPool=$elt->{pool}",
417 $bweb->update_media();
419 } elsif ($action eq 'client_status') {
420 $bweb->can_do('r_client_status');
422 foreach my $client (CGI::param('client')) {
423 if ($client =~ $client_re) {
425 $b = new Bconsole(pref => $conf)
429 content => $b->send_cmd("st client=$client"),
430 title => "Client status",
435 $bweb->error("Can't get client selection");
439 } elsif ($action eq 'cancel_job') {
442 } elsif ($action eq 'cancel_future_job') {
443 $bweb->cancel_future_job();
445 } elsif ($action eq 'media_zoom') {
446 $bweb->display_media_zoom();
448 } elsif ($action eq 'job_zoom') {
450 $bweb->display_job_zoom($arg->{jobid});
451 $bweb->get_job_log();
453 } elsif ($action eq 'job_log') {
454 $bweb->get_job_log();
456 } elsif ($action eq 'prune') {
459 } elsif ($action eq 'purge') {
462 } elsif ($action eq 'run_job') {
465 } elsif ($action eq 'run_job_mod') {
466 $bweb->run_job_mod();
468 } elsif ($action eq 'run_job_now') {
469 $bweb->run_job_now();
471 } elsif ($action eq 'label_barcodes') {
472 $bweb->label_barcodes();
474 } elsif ($action eq 'delete') {
477 } elsif ($action eq 'fileset_view') {
478 $bweb->fileset_view();
480 } elsif ($action eq 'next_job2') {
481 $bweb->display_next_job();
483 } elsif ($action eq 'missing') {
484 $bweb->display_missing_job();
486 } elsif ($action eq 'overview') {
487 $bweb->can_do('r_view_job');
488 print "<div><table border='0'><tr><td valign='top'>\n";
489 my $fields = $bweb->get_form(qw/level filter age jobtype since type
490 db_client_groups qclient_groups/); # drop this to hide
491 $fields->{hide_status}=1;
492 $fields->{view_time_slice}=1;
493 $fields->{action}='overview';
494 $bweb->display($fields, "display_form_job.tpl");
496 print "</td><td valign='top'>";
497 $bweb->display_overview();
498 print "</td></tr></table></div>";
500 } elsif ($action eq 'overview_zoom') {
501 $bweb->can_do('r_view_job');
502 print "<div><table border='0'><tr><td valign='top'>\n";
503 my $fields = $bweb->get_form(qw/level filter age jobtype since type
504 db_client_groups qclient_groups/); # drop this to hide
505 $fields->{hide_status}=1;
506 $fields->{view_time_slice}=1;
507 $fields->{action}='overview_zoom';
508 $bweb->display($fields, "display_form_job.tpl");
509 print "</td><td valign='top'>";
510 $bweb->display_overview_zoom();
511 print "</td></tr></table></div>";
514 $bweb->error("Sorry, this action doesn't exist");
517 $bweb->display_end();
519 $bweb->dbh_disconnect();
525 o Affichage des medias qui ont besoin d'etre change
526 o Affichage des infos de query.sql
528 - Affichage des du TapeAlert sur le site
529 - Recuperation des erreurs SCSI de /var/log/kern.log