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';
45 my $conf = new Bweb::Config(config_file => $Bweb::config_file);
48 my $bweb = new Bweb(info => $conf);
49 my $arg = $bweb->get_form('jobid', 'limit', 'offset', 'age', 'new_dir');
51 # just send data with text/brestore content
52 if ($action eq 'restore') {
53 print CGI::header('text/brestore'); # specialy to run brestore.pl
58 $bweb->display_begin();
60 # if no configuration, we send edit_conf
61 if ($action ne 'apply_conf' and !$bweb->{info}->{dbi}) {
62 $action = 'edit_conf';
65 if ($action eq 'begin') { # main display
66 print "<div style='left=0;'><table border='0'><tr><td valign='top' width='100%'>\n";
67 $bweb->display_general(age => $arg->{age});
68 $bweb->display_running_jobs(0);
69 print "</td><td valign='top'>";
70 $bweb->display({}, "stats.tpl");
71 print "</td></tr></table></div>";
72 $bweb->display_job(limit => 10);
74 } elsif ($action eq 'view_conf') {
75 $bweb->can_do('r_configure');
78 } elsif ($action eq 'edit_conf') {
79 $bweb->can_do('r_configure');
82 } elsif ($action eq 'apply_conf') {
83 $bweb->can_do('r_configure');
86 } elsif ($action eq 'user_del') {
89 } elsif ($action eq 'user_add') {
92 } elsif ($action eq 'user_edit') {
93 $bweb->display_user();
95 } elsif ($action eq 'user_save') {
98 } elsif ($action eq 'users') {
99 $bweb->display_users();
101 } elsif ($action eq 'client') {
102 $bweb->display_clients();
104 } elsif ($action eq 'client_edit') {
105 $bweb->client_edit();
107 } elsif ($action eq 'client_save') {
108 $bweb->client_save();
110 } elsif ($action eq 'pool') {
111 $bweb->display_pool();
113 } elsif ($action eq 'location_edit') {
114 $bweb->location_edit();
116 } elsif ($action eq 'location_save') {
117 $bweb->location_save();
119 } elsif ($action eq 'location_add') {
120 $bweb->location_add();
122 } elsif ($action eq 'location_del') {
123 $bweb->location_del();
125 } elsif ($action eq 'cmd_storage') {
126 $bweb->cmd_storage();
128 } elsif ($action eq 'list_files') {
129 $bweb->display_files();
131 } elsif ($action eq 'media') {
132 $bweb->can_do('r_view_media');
134 print "<div><table border='0'><tr><td valign='top'>\n";
135 my $fields = $bweb->get_form(qw/db_locations db_pools expired
136 qlocations qpools volstatus qre_media
137 limit qmediatypes db_mediatypes/);
138 $bweb->display($fields, "display_form_media.tpl");
140 print "</td><td valign='top'>";
141 $bweb->display_media(offset => $arg->{offset},
142 limit => $arg->{limit});
143 print "</td></tr></table></div>";
145 } elsif ($action eq 'allmedia') {
146 $bweb->display_allmedia();
148 } elsif ($action eq 'eject') {
149 $bweb->can_do('r_autochanger_mgnt');
151 my $arg = $bweb->get_form("ach");
152 my $a = $bweb->ach_get($arg->{ach});
156 foreach my $slot (CGI::param('slot')) {
157 print $a->{error} unless $a->send_to_io($slot);
160 foreach my $media (CGI::param('media')) {
161 my $slot = $a->get_media_slot($media);
162 print $a->{error} unless $a->send_to_io($slot);
165 $a->display_content();
167 } elsif ($action eq 'add_media') {
170 } elsif ($action eq 'eject_media') {
171 $bweb->eject_media();
173 } elsif ($action eq 'clear_io') {
174 $bweb->can_do('r_autochanger_mgnt');
176 my $arg = $bweb->get_form('ach');
178 my $a = $bweb->ach_get($arg->{ach});
182 $a->display_content();
185 } elsif ($action eq 'ach_edit') {
188 } elsif ($action eq 'ach_del') {
191 } elsif ($action eq 'ach_view') {
192 $bweb->can_do('r_autochanger_mgnt');
194 # TODO : get autochanger name and create it
196 my $arg = $bweb->get_form('ach');
198 my $a = $bweb->ach_get($arg->{ach});
201 $a->display_content();
204 } elsif ($action eq 'ach_add') {
207 } elsif ($action eq 'ach_load') {
208 $bweb->can_do('r_autochanger_mgnt');
210 my $arg = $bweb->get_form('ach', 'drive', 'slot');
212 my $a = $bweb->ach_get($arg->{ach});
214 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
216 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
217 # TODO : use template here
219 $b->send_cmd("mount slot=$arg->{slot} drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
222 $bweb->error("Can't get drive, slot or ach");
225 } elsif ($action eq 'ach_unload') {
226 $bweb->can_do('r_autochanger_mgnt');
228 my $arg = $bweb->get_form('drive', 'slot', 'ach');
230 my $a = $bweb->ach_get($arg->{ach});
232 if (defined $a and defined $arg->{drive} and defined $arg->{slot})
234 my $b = new Bconsole(pref => $conf, timeout => 300, log_stdout => 1) ;
235 # TODO : use template here
237 $b->send_cmd("umount drive=$arg->{drive} storage=\"" . $a->get_drive_name($arg->{drive}) . '"');
241 $bweb->error("Can't get drive, slot or ach");
243 } elsif ($action eq 'intern_media') {
244 $bweb->help_intern();
246 } elsif ($action eq 'compute_intern_media') {
247 $bweb->help_intern_compute();
249 } elsif ($action eq 'extern_media') {
250 $bweb->help_extern();
252 } elsif ($action eq 'compute_extern_media') {
253 $bweb->help_extern_compute();
255 } elsif ($action eq 'extern') {
256 $bweb->can_do('r_media_mgnt');
257 $bweb->can_do('r_autochanger_mgnt');
259 print "<div style='float: left;'>";
260 my @achs = $bweb->eject_media();
261 for my $ach (@achs) {
262 CGI::param('ach', $ach);
263 $bweb->update_slots();
265 print "</div><div style='float: left;margin-left: 20px;'>";
266 $bweb->move_media('yes'); # pb with enabled = no for restore
269 } elsif ($action eq 'move_email') {
272 } elsif ($action eq 'change_location') {
273 $bweb->location_change();
275 } elsif ($action eq 'location') {
276 $bweb->location_display();
278 } elsif ($action eq 'about') {
279 $bweb->display($bweb, 'about.tpl');
281 } elsif ($action eq 'intern') {
282 $bweb->move_media('yes'); # TODO : remove that
284 } elsif ($action eq 'move_media') {
285 my $a = $bweb->get_form('enabled');
286 $bweb->move_media($a->{enabled});
288 } elsif ($action eq 'save_location') {
289 $bweb->save_location();
291 } elsif ($action eq 'update_location') {
292 $bweb->update_location();
294 } elsif ($action eq 'update_media') {
295 $bweb->update_media();
297 } elsif ($action eq 'do_update_media') {
298 $bweb->do_update_media();
300 } elsif ($action eq 'update_slots') {
301 $bweb->update_slots();
303 } elsif ($action eq 'graph') {
304 $bweb->display_graph();
306 } elsif ($action eq 'next_job') {
307 $bweb->director_show_sched();
309 } elsif ($action eq 'enable_job') {
310 $bweb->enable_disable_job(1);
312 } elsif ($action eq 'disable_job') {
313 $bweb->enable_disable_job(0);
315 } elsif ($action eq 'groups') {
316 $bweb->display_groups();
318 } elsif ($action eq 'groups_edit') {
319 $bweb->groups_edit();
321 } elsif ($action eq 'groups_save') {
322 $bweb->groups_save();
324 } elsif ($action eq 'groups_del') {
327 } elsif ($action eq 'job') {
328 $bweb->can_do('r_view_job');
329 print "<div><table border='0'><tr><td valign='top'>\n";
330 my $fields = $bweb->get_form(qw/status level filter db_clients
332 limit age offset qclients qfilesets
333 jobtype qpools db_pools
334 db_client_groups qclient_groups/); # drop this to hide
335 if (!CGI::param('since')) {
336 $fields->{hide_since}=1 ;
337 delete $fields->{since};
339 $bweb->display($fields, "display_form_job.tpl");
341 print "</td><td valign='top'>";
342 $bweb->display_job(age => $fields->{age}, # last 7 days
343 since => $fields->{since},
344 offset => $fields->{offset},
345 limit => $fields->{limit});
346 print "</td></tr></table></div>";
347 } elsif ($action eq 'job_group') {
348 $bweb->can_do('r_view_job');
349 print "<div><table border='0'><tr><td valign='top'>\n";
350 my $fields = $bweb->get_form(qw/limit level age filter
351 db_client_groups qclient_groups/); # drop this to hide
353 $fields->{hide_status} = 1;
354 $fields->{hide_type} = 1;
355 $fields->{hide_since}=1;
356 $fields->{action} = 'job_group';
358 $bweb->display($fields, "display_form_job.tpl");
360 print "</td><td valign='top'>";
361 $bweb->display_job_group(age => $arg->{age}, # last 7 days
362 limit => $arg->{limit});
363 print "</td></tr></table></div>";
364 } elsif ($action eq 'client_stats') {
366 foreach my $client (CGI::param('client')) {
367 if ($client =~ $client_re) {
368 $bweb->display_client_stats(clientname => $1,
372 } elsif ($action eq 'group_stats') {
373 $bweb->can_do('r_view_stat');
374 print "<div><table border='0'><tr><td valign='top'>\n";
375 my $fields = $bweb->get_form(qw/since age
376 db_client_groups qclient_groups/);
377 $fields->{action}='group_stats';
378 $fields->{hide_level}=1;
379 $fields->{hide_type}=1;
380 $fields->{hide_status}=1;
382 $bweb->display($fields, "display_form_job.tpl");
384 print "</td><td valign='top'>";
385 $bweb->display_group_stats();
387 print "</td></tr></table></div>"
389 } elsif ($action eq 'running') {
390 $bweb->display_running_jobs(1);
392 } elsif ($action eq 'dsp_cur_job') {
393 $bweb->display_running_job();
395 } elsif ($action eq 'update_from_pool') {
396 $bweb->can_do('r_media_mgnt');
397 my $elt = $bweb->get_form(qw/media pool/);
398 unless ($elt->{media} || $elt->{pool}) {
399 $bweb->error("Can't get media or pool param");
401 my $b = new Bconsole(pref => $conf) ;
404 content => $b->send_cmd("update volume=$elt->{media} fromPool=$elt->{pool}"),
405 title => "Update pool",
406 name => "update volume=$elt->{media} fromPool=$elt->{pool}",
410 $bweb->update_media();
412 } elsif ($action eq 'client_status') {
413 $bweb->can_do('r_client_status');
415 foreach my $client (CGI::param('client')) {
416 if ($client =~ $client_re) {
418 $b = new Bconsole(pref => $conf)
422 content => $b->send_cmd("st client=$client"),
423 title => "Client status",
428 $bweb->error("Can't get client selection");
432 } elsif ($action eq 'cancel_job') {
435 } elsif ($action eq 'cancel_future_job') {
436 $bweb->cancel_future_job();
438 } elsif ($action eq 'media_zoom') {
439 $bweb->display_media_zoom();
441 } elsif ($action eq 'job_zoom') {
443 $bweb->display_job_zoom($arg->{jobid});
444 $bweb->get_job_log();
446 } elsif ($action eq 'job_log') {
447 $bweb->get_job_log();
449 } elsif ($action eq 'prune') {
452 } elsif ($action eq 'purge') {
455 } elsif ($action eq 'run_job') {
458 } elsif ($action eq 'run_job_mod') {
459 $bweb->run_job_mod();
461 } elsif ($action eq 'run_job_now') {
462 $bweb->run_job_now();
464 } elsif ($action eq 'label_barcodes') {
465 $bweb->label_barcodes();
467 } elsif ($action eq 'delete') {
470 } elsif ($action eq 'fileset_view') {
471 $bweb->fileset_view();
473 } elsif ($action eq 'next_job2') {
474 $bweb->display_next_job();
476 } elsif ($action eq 'missing') {
477 $bweb->display_missing_job();
479 } elsif ($action eq 'overview') {
480 $bweb->can_do('r_view_job');
481 print "<div><table border='0'><tr><td valign='top'>\n";
482 my $fields = $bweb->get_form(qw/level filter age jobtype since type
483 db_client_groups qclient_groups/); # drop this to hide
484 $fields->{hide_status}=1;
485 $fields->{view_time_slice}=1;
486 $fields->{action}='overview';
487 $bweb->display($fields, "display_form_job.tpl");
489 print "</td><td valign='top'>";
490 $bweb->display_overview();
491 print "</td></tr></table></div>";
493 } elsif ($action eq 'overview_zoom') {
494 $bweb->can_do('r_view_job');
495 print "<div><table border='0'><tr><td valign='top'>\n";
496 my $fields = $bweb->get_form(qw/level filter age jobtype since type
497 db_client_groups qclient_groups/); # drop this to hide
498 $fields->{hide_status}=1;
499 $fields->{view_time_slice}=1;
500 $fields->{action}='overview_zoom';
501 $bweb->display($fields, "display_form_job.tpl");
502 print "</td><td valign='top'>";
503 $bweb->display_overview_zoom();
504 print "</td></tr></table></div>";
507 $bweb->error("Sorry, this action doesn't exist");
510 $bweb->display_end();
512 $bweb->dbh_disconnect();
518 o Affichage des medias qui ont besoin d'etre change
519 o Affichage des infos de query.sql
521 - Affichage des du TapeAlert sur le site
522 - Recuperation des erreurs SCSI de /var/log/kern.log