5 Bweb - A Bacula web interface
6 Bacula® - The Network Backup Solution
8 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
10 The main author of Bweb is Eric Bollengier.
11 The main author of Bacula is Kern Sibbald, with contributions from
12 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 two of the GNU General Public
16 License as published by the Free Software Foundation plus additions
17 that are listed in the file LICENSE.
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 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 John Walker.
30 The licensor of Bacula is the Free Software Foundation Europe
31 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
32 Switzerland, email:ftf@fsfeurope.org.
41 ################################################################
42 # Manage with Expect the bconsole tool
47 # my $pref = new Pref(config_file => 'brestore.conf');
48 # my $bconsole = new Bconsole(pref => $pref);
51 my ($class, %arg) = @_;
54 pref => $arg{pref}, # Pref object
55 bconsole => undef, # Expect object
56 log_stdout => $arg{log_stdout} || 0,
57 timeout => $arg{timeout} || 20,
58 debug => $arg{debug} || 0,
66 my ($self, %arg) = @_;
69 for my $key (keys %arg) {
71 $arg{$key} =~ tr/""/ /;
72 $cmd .= "$key=\"$arg{$key}\" ";
76 unless ($self->connect()) {
80 print STDERR "===> $cmd yes\n";
81 $self->{bconsole}->clear_accum();
82 $self->send("$cmd yes\n");
83 $self->expect_it('-re',qr/^[*]/);
84 my $ret = $self->before();
85 if ($ret =~ /jobid=(\d+)/is) {
92 # for brestore.pl::BwebConsole
100 my ($self, $what) = @_;
101 $self->{bconsole}->send($what);
106 my ($self, @what) = @_;
107 unless ($self->{bconsole}->expect($self->{timeout}, @what)) {
116 my ($self, $how) = @_;
118 if ($self->{bconsole}) {
119 $self->{bconsole}->log_stdout($how);
122 $self->{log_stdout} = $how;
127 my ($self, $error) = @_;
129 if ($self->{debug}) {
130 print "E: bconsole (", $self->{pref}->{bconsole}, ") $!\n";
139 if ($self->{error}) {
143 unless ($self->{bconsole}) {
144 my @cmd = split(/\s+/, $self->{pref}->{bconsole}) ;
146 return $self->error("bconsole string not found");
148 $self->{bconsole} = new Expect;
149 $self->{bconsole}->raw_pty(0);
150 $self->{bconsole}->debug($self->{debug});
151 $self->{bconsole}->log_stdout($self->{debug} || $self->{log_stdout});
153 # WARNING : die is trapped by gtk_main_loop()
154 # and exit() closes DBI connection
157 my $sav = $SIG{__DIE__};
158 $SIG{__DIE__} = sub { _exit 1 ;};
159 my $old = $ENV{COLUMNS};
161 $ret = $self->{bconsole}->spawn(@cmd) ;
162 delete $ENV{COLUMNS};
163 $ENV{COLUMNS} = $old if ($old) ;
164 $SIG{__DIE__} = $sav;
168 return $self->error($ret);
171 # TODO : we must verify that expect return the good value
173 $self->expect_it('*');
174 $self->send_cmd('gui on');
181 my ($self, $jobid) = @_;
182 return $self->send_cmd("cancel jobid=$jobid");
185 # get text between to expect
189 return $self->{bconsole}->before();
194 my ($self, $cmd) = @_;
195 unless ($self->connect()) {
198 $self->send("$cmd\n");
199 $self->expect_it($cmd);
200 $self->{bconsole}->clear_accum();
201 $self->expect_it('-re',qr/^[*]/);
202 return $self->before();
207 my ($self, $cmd) = @_;
208 unless ($self->connect()) {
211 $self->send("$cmd\n");
212 $self->expect_it('-re', '[?].+:');
214 $self->send("yes\n");
215 $self->expect_it("yes");
216 $self->{bconsole}->clear_accum();
217 $self->expect_it('-re',qr/^[*]/);
218 return $self->before();
223 my ($self, %arg) = @_;
225 unless ($arg{storage}) {
229 unless ($self->connect()) {
233 $arg{drive} = $arg{drive} || '0' ;
234 $arg{pool} = $arg{pool} || 'Scratch';
236 my $cmd = "label barcodes drive=$arg{drive} pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
239 $cmd .= " slots=$arg{slots}";
242 $self->send("$cmd\n");
243 $self->expect_it('-re', '[?].+\).*:');
244 my $res = $self->before();
245 $self->send("yes\n");
246 $self->expect_it("yes");
247 $res .= $self->before();
248 $self->expect_it('-re',qr/^[*]/);
249 $res .= $self->before();
254 # return [ { name => 'test1', vol => '00001', ... },
255 # { name => 'test2', vol => '00002', ... }... ]
257 sub director_get_sched
259 my ($self, $days) = @_ ;
263 unless ($self->connect()) {
267 my $status = $self->send_cmd("st director days=$days") ;
270 foreach my $l (split(/\r?\n/, $status)) {
271 #Level Type Pri Scheduled Name Volume
272 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
273 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
274 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
276 my $vol = pop @name_vol; # last element
277 my $name = join(" ", @name_vol); # can contains space
295 my ($self, $storage, $drive) = @_;
296 $drive = $drive || 0;
298 return $self->send_cmd("update slots storage=$storage drive=$drive");
303 my ($self, $fs) = @_;
305 my $out = $self->send_cmd("show fileset=\"$fs\"");
309 foreach my $l (split(/\r\n/, $out)) {
311 if ($l =~ /^\s+([I|E])\s+(.+)$/) { # include
312 push @{$ret->{$1}}, { file => $2 };
322 return split(/\r\n/, $self->send_cmd(".jobs"));
328 return split(/\r\n/, $self->send_cmd(".filesets"));
334 return split(/\r\n/, $self->send_cmd(".storage"));
340 return split(/\r\n/, $self->send_cmd(".clients"));
346 return split(/\r\n/, $self->send_cmd(".pools"));
349 use Time::ParseDate qw/parsedate/;
350 use POSIX qw/strftime/;
355 my ($self, @volume) = @_;
356 return '' unless (@volume);
359 foreach my $vol (@volume) {
360 if ($vol =~ /^([\w\d\.-]+)$/) {
361 $sel .= " volume=$1";
364 $self->error("Sorry media is bad");
374 my ($self, @volume) = @_;
376 my $sel = $self->_get_volume(@volume);
379 $ret = $self->send_cmd("purge $sel");
381 $ret = $self->{error};
388 my ($self, @volume) = @_;
390 my $sel = $self->_get_volume(@volume);
393 $ret = $self->send_cmd("prune $sel yes");
395 $ret = $self->{error};
402 my ($self, @jobid) = @_;
404 return 0 unless (@jobid);
407 foreach my $job (@jobid) {
408 if ($job =~ /^(\d+)$/) {
412 return $self->error("Sorry jobid is bad");
416 $self->send_cmd("purge $sel");
422 $self->send("quit\n");
423 $self->{bconsole}->soft_close();
424 $self->{bconsole} = undef;
432 # grep -v __END__ Bconsole.pm | perl
436 print "test sans conio\n";
438 my $c = new Bconsole(pref => {
439 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
443 print "fileset : ", join(',', $c->list_fileset()), "\n";
444 print "job : ", join(',', $c->list_job()), "\n";
445 print "storage : ", join(',', $c->list_storage()), "\n";
446 #print "prune : " . $c->prune_volume('000001'), "\n";
447 #print "update : " . $c->send_cmd('update slots storage=SDLT-1-2, drive=0'), "\n";
448 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
450 # drive => 0)), "\n";