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;
129 if ($self->{error}) {
133 unless ($self->{bconsole}) {
134 my @cmd = split(/\s+/, $self->{pref}->{bconsole}) ;
136 $self->{error} = "bconsole string not found";
139 $self->{bconsole} = new Expect;
140 $self->{bconsole}->raw_pty(0);
141 $self->{bconsole}->debug($self->{debug});
142 $self->{bconsole}->log_stdout($self->{debug} || $self->{log_stdout});
144 # WARNING : die is trapped by gtk_main_loop()
145 # and exit() closes DBI connection
148 my $sav = $SIG{__DIE__};
149 $SIG{__DIE__} = sub { _exit 1 ;};
150 my $old = $ENV{COLUMNS};
152 $ret = $self->{bconsole}->spawn(@cmd) ;
153 $ENV{COLUMNS} = $old;
154 $SIG{__DIE__} = $sav;
162 # TODO : we must verify that expect return the good value
164 $self->expect_it('*');
165 $self->send_cmd('gui on');
172 my ($self, $jobid) = @_;
173 return $self->send_cmd("cancel jobid=$jobid");
176 # get text between to expect
180 return $self->{bconsole}->before();
185 my ($self, $cmd) = @_;
186 unless ($self->connect()) {
189 $self->send("$cmd\n");
190 $self->expect_it($cmd);
191 $self->{bconsole}->clear_accum();
192 $self->expect_it('-re',qr/^[*]/);
193 return $self->before();
198 my ($self, $cmd) = @_;
199 unless ($self->connect()) {
202 $self->send("$cmd\n");
203 $self->expect_it('-re', '[?].+:');
205 $self->send("yes\n");
206 $self->expect_it("yes");
207 $self->{bconsole}->clear_accum();
208 $self->expect_it('-re',qr/^[*]/);
209 return $self->before();
214 my ($self, %arg) = @_;
216 unless ($arg{storage}) {
220 unless ($self->connect()) {
224 $arg{drive} = $arg{drive} || '0' ;
225 $arg{pool} = $arg{pool} || 'Scratch';
227 my $cmd = "label barcodes drive=$arg{drive} pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
230 $cmd .= " slots=$arg{slots}";
233 $self->send("$cmd\n");
234 $self->expect_it('-re', '[?].+\).*:');
235 my $res = $self->before();
236 $self->send("yes\n");
237 $self->expect_it("yes");
238 $res .= $self->before();
239 $self->expect_it('-re',qr/^[*]/);
240 $res .= $self->before();
245 # return [ { name => 'test1', vol => '00001', ... },
246 # { name => 'test2', vol => '00002', ... }... ]
248 sub director_get_sched
250 my ($self, $days) = @_ ;
254 unless ($self->connect()) {
258 my $status = $self->send_cmd("st director days=$days") ;
261 foreach my $l (split(/\r?\n/, $status)) {
262 #Level Type Pri Scheduled Name Volume
263 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
264 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
265 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
267 my $vol = pop @name_vol; # last element
268 my $name = join(" ", @name_vol); # can contains space
286 my ($self, $storage, $drive) = @_;
287 $drive = $drive || 0;
289 return $self->send_cmd("update slots storage=$storage drive=$drive");
294 my ($self, $fs) = @_;
296 my $out = $self->send_cmd("show fileset=\"$fs\"");
300 foreach my $l (split(/\r\n/, $out)) {
302 if ($l =~ /^\s+([I|E])\s+(.+)$/) { # include
303 push @{$ret->{$1}}, { file => $2 };
313 return split(/\r\n/, $self->send_cmd(".jobs"));
319 return split(/\r\n/, $self->send_cmd(".filesets"));
325 return split(/\r\n/, $self->send_cmd(".storage"));
331 return split(/\r\n/, $self->send_cmd(".clients"));
337 return split(/\r\n/, $self->send_cmd(".pools"));
340 use Time::ParseDate qw/parsedate/;
341 use POSIX qw/strftime/;
346 my ($self, @volume) = @_;
347 return '' unless (@volume);
350 foreach my $vol (@volume) {
351 if ($vol =~ /^([\w\d\.-]+)$/) {
352 $sel .= " volume=$1";
355 $self->{error} = "Sorry media is bad";
365 my ($self, @volume) = @_;
367 my $sel = $self->_get_volume(@volume);
370 $ret = $self->send_cmd("purge $sel");
372 $ret = $self->{error};
379 my ($self, @volume) = @_;
381 my $sel = $self->_get_volume(@volume);
384 $ret = $self->send_cmd("prune $sel yes");
386 $ret = $self->{error};
393 my ($self, @jobid) = @_;
395 return 0 unless (@jobid);
398 foreach my $job (@jobid) {
399 if ($job =~ /^(\d+)$/) {
403 $self->{error} = "Sorry jobid is bad";
408 $self->send_cmd("purge $sel");
414 $self->send("quit\n");
415 $self->{bconsole}->soft_close();
416 $self->{bconsole} = undef;
424 # grep -v __END__ Bconsole.pm | perl
428 print "test sans conio\n";
430 my $c = new Bconsole(pref => {
431 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
435 print "fileset : ", join(',', $c->list_fileset()), "\n";
436 print "job : ", join(',', $c->list_job()), "\n";
437 print "storage : ", join(',', $c->list_storage()), "\n";
438 #print "prune : " . $c->prune_volume('000001'), "\n";
439 #print "update : " . $c->send_cmd('update slots storage=SDLT-1-2, drive=0'), "\n";
440 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
442 # drive => 0)), "\n";