5 Copyright (C) 2006 Eric Bollengier
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 ################################################################
30 # Manage with Expect the bconsole tool
35 # my $pref = new Pref(config_file => 'brestore.conf');
36 # my $bconsole = new Bconsole(pref => $pref);
39 my ($class, %arg) = @_;
42 pref => $arg{pref}, # Pref object
43 bconsole => undef, # Expect object
44 log_stdout => $arg{log_stdout} || 0,
45 timeout => $arg{timeout} || 20,
46 debug => $arg{debug} || 0,
54 my ($self, %arg) = @_;
57 for my $key (keys %arg) {
59 $arg{$key} =~ tr/""/ /;
60 $cmd .= "$key=\"$arg{$key}\" ";
64 unless ($self->connect()) {
68 print STDERR "===> $cmd yes\n";
69 $self->{bconsole}->clear_accum();
70 $self->send("$cmd yes\n");
71 $self->expect_it('-re',qr/^[*]/);
72 my $ret = $self->before();
73 if ($ret =~ /jobid=(\d+)/is) {
80 # for brestore.pl::BwebConsole
88 my ($self, $what) = @_;
89 $self->{bconsole}->send($what);
94 my ($self, @what) = @_;
95 unless ($self->{bconsole}->expect($self->{timeout}, @what)) {
104 my ($self, $how) = @_;
106 if ($self->{bconsole}) {
107 $self->{bconsole}->log_stdout($how);
110 $self->{log_stdout} = $how;
117 if ($self->{error}) {
121 unless ($self->{bconsole}) {
122 my @cmd = split(/\s+/, $self->{pref}->{bconsole}) ;
124 $self->{error} = "bconsole string not found";
127 $self->{bconsole} = new Expect;
128 $self->{bconsole}->raw_pty(0);
129 $self->{bconsole}->debug($self->{debug});
130 $self->{bconsole}->log_stdout($self->{debug} || $self->{log_stdout});
132 # WARNING : die is trapped by gtk_main_loop()
133 # and exit() closes DBI connection
136 my $sav = $SIG{__DIE__};
137 $SIG{__DIE__} = sub { _exit 1 ;};
138 $ret = $self->{bconsole}->spawn(@cmd) ;
139 $SIG{__DIE__} = $sav;
147 # TODO : we must verify that expect return the good value
149 $self->expect_it('*');
150 $self->send_cmd('gui on');
157 my ($self, $jobid) = @_;
158 return $self->send_cmd("cancel jobid=$jobid");
161 # get text between to expect
165 return $self->{bconsole}->before();
170 my ($self, $cmd) = @_;
171 unless ($self->connect()) {
174 $self->send("$cmd\n");
175 $self->expect_it($cmd);
176 $self->{bconsole}->clear_accum();
177 $self->expect_it('-re',qr/^[*]/);
178 return $self->before();
183 my ($self, $cmd) = @_;
184 unless ($self->connect()) {
187 $self->send("$cmd\n");
188 $self->expect_it('-re', '[?].+:');
190 $self->send("yes\n");
191 $self->expect_it("yes");
192 $self->{bconsole}->clear_accum();
193 $self->expect_it('-re',qr/^[*]/);
194 return $self->before();
199 my ($self, %arg) = @_;
201 unless ($arg{storage}) {
205 unless ($self->connect()) {
209 $arg{drive} = $arg{drive} || '0' ;
210 $arg{pool} = $arg{pool} || 'Scratch';
212 my $cmd = "label barcodes drive=$arg{drive} pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
215 $cmd .= " slots=$arg{slots}";
218 $self->send("$cmd\n");
219 $self->expect_it('-re', '[?].+\)\s*:');
220 my $res = $self->before();
221 $self->send("yes\n");
222 $self->expect_it("yes");
223 $res .= $self->before();
224 $self->expect_it('-re',qr/^[*]/);
225 $res .= $self->before();
230 # return [ { name => 'test1', vol => '00001', ... },
231 # { name => 'test2', vol => '00002', ... }... ]
233 sub director_get_sched
235 my ($self, $days) = @_ ;
239 unless ($self->connect()) {
243 my $status = $self->send_cmd("st director days=$days") ;
246 foreach my $l (split(/\r?\n/, $status)) {
247 #Level Type Pri Scheduled Name Volume
248 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
249 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
250 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
252 my $vol = pop @name_vol; # last element
253 my $name = join(" ", @name_vol); # can contains space
271 my ($self, $storage, $drive) = @_;
272 $drive = $drive || 0;
274 return $self->send_cmd("update slots storage=$storage drive=$drive");
279 my ($self, $fs) = @_;
281 my $out = $self->send_cmd("show fileset=\"$fs\"");
285 foreach my $l (split(/\r\n/, $out)) {
287 if ($l =~ /^\s+([I|E])\s+(.+)$/) { # include
288 push @{$ret->{$1}}, { file => $2 };
298 return split(/\r\n/, $self->send_cmd(".jobs"));
304 return split(/\r\n/, $self->send_cmd(".filesets"));
310 return split(/\r\n/, $self->send_cmd(".storage"));
316 return split(/\r\n/, $self->send_cmd(".clients"));
322 return split(/\r\n/, $self->send_cmd(".pools"));
325 use Time::ParseDate qw/parsedate/;
326 use POSIX qw/strftime/;
331 my ($self, @volume) = @_;
332 return '' unless (@volume);
335 foreach my $vol (@volume) {
336 if ($vol =~ /^([\w\d\.-]+)$/) {
337 $sel .= " volume=$1";
340 $self->{error} = "Sorry media is bad";
350 my ($self, @volume) = @_;
352 my $sel = $self->_get_volume(@volume);
355 $ret = $self->send_cmd("purge $sel");
357 $ret = $self->{error};
364 my ($self, @volume) = @_;
366 my $sel = $self->_get_volume(@volume);
369 $ret = $self->send_cmd("prune $sel yes");
371 $ret = $self->{error};
378 my ($self, @jobid) = @_;
380 return 0 unless (@jobid);
383 foreach my $job (@jobid) {
384 if ($job =~ /^(\d+)$/) {
388 $self->{error} = "Sorry jobid is bad";
393 $self->send_cmd("purge $sel");
399 $self->send("quit\n");
400 $self->{bconsole}->soft_close();
401 $self->{bconsole} = undef;
409 # grep -v __END__ Bconsole.pm | perl
413 print "test sans conio\n";
415 my $c = new Bconsole(pref => {
416 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
420 print "fileset : ", join(',', $c->list_fileset()), "\n";
421 print "job : ", join(',', $c->list_job()), "\n";
422 print "storage : ", join(',', $c->list_storage()), "\n";
423 #print "prune : " . $c->prune_volume('000001'), "\n";
424 #print "update : " . $c->send_cmd('update slots storage=SDLT-1-2, drive=0'), "\n";
425 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
427 # drive => 0)), "\n";