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 "=> $cmd yes\n";
70 $self->{bconsole}->clear_accum();
71 $self->send("$cmd yes\n");
72 $self->expect_it('-re',qr/^[*]/);
73 my $ret = $self->before();
74 if ($ret =~ /jobid=(\d+)/is) {
83 my ($self, $what) = @_;
84 $self->{bconsole}->send($what);
89 my ($self, @what) = @_;
90 unless ($self->{bconsole}->expect($self->{timeout}, @what)) {
99 my ($self, $how) = @_;
101 if ($self->{bconsole}) {
102 $self->{bconsole}->log_stdout($how);
105 $self->{log_stdout} = $how;
112 if ($self->{error}) {
116 unless ($self->{bconsole}) {
117 my @cmd = split(/\s+/, $self->{pref}->{bconsole}) ;
119 $self->{error} = "bconsole string not found";
122 $self->{bconsole} = new Expect;
123 $self->{bconsole}->raw_pty(0);
124 $self->{bconsole}->debug($self->{debug});
125 $self->{bconsole}->log_stdout($self->{debug} || $self->{log_stdout});
127 # WARNING : die is trapped by gtk_main_loop()
128 # and exit() closes DBI connection
131 my $sav = $SIG{__DIE__};
132 $SIG{__DIE__} = sub { _exit 1 ;};
133 $ret = $self->{bconsole}->spawn(@cmd) ;
134 $SIG{__DIE__} = $sav;
142 # TODO : we must verify that expect return the good value
144 $self->expect_it('*');
145 $self->send_cmd('gui on');
152 my ($self, $jobid) = @_;
153 return $self->send_cmd("cancel jobid=$jobid");
156 # get text between to expect
160 return $self->{bconsole}->before();
165 my ($self, $cmd) = @_;
166 unless ($self->connect()) {
169 $self->send("$cmd\n");
170 $self->expect_it($cmd);
171 $self->{bconsole}->clear_accum();
172 $self->expect_it('-re',qr/^[*]/);
173 return $self->before();
178 my ($self, $cmd) = @_;
179 unless ($self->connect()) {
182 $self->send("$cmd\n");
183 $self->expect_it('-re', '[?].+:');
185 $self->send("yes\n");
186 $self->expect_it("yes");
187 $self->{bconsole}->clear_accum();
188 $self->expect_it('-re',qr/^[*]/);
189 return $self->before();
194 my ($self, %arg) = @_;
196 unless ($arg{storage}) {
200 unless ($self->connect()) {
204 $arg{drive} = $arg{drive} || '0' ;
205 $arg{pool} = $arg{pool} || 'Scratch';
207 my $cmd = "label barcodes pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
210 $cmd .= " slots=$arg{slots}";
213 $self->send("$cmd\n");
214 $self->expect_it('-re', '\[0\]\s*:');
215 $self->send("$arg{drive}\n");
216 $self->expect_it('-re', '[?].+\)\s*:');
217 my $res = $self->before();
218 $self->send("yes\n");
219 $self->expect_it("yes");
220 $res .= $self->before();
221 $self->expect_it('-re',qr/^[*]/);
222 $res .= $self->before();
227 # return [ { name => 'test1', vol => '00001', ... },
228 # { name => 'test2', vol => '00002', ... }... ]
230 sub director_get_sched
232 my ($self, $days) = @_ ;
236 unless ($self->connect()) {
240 my $status = $self->send_cmd("st director days=$days") ;
243 foreach my $l (split(/\r?\n/, $status)) {
244 #Level Type Pri Scheduled Name Volume
245 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
246 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
247 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
249 my $vol = pop @name_vol; # last element
250 my $name = join(" ", @name_vol); # can contains space
268 my ($self, $storage, $drive) = @_;
269 $drive = $drive || 0;
271 return $self->send_cmd("update slots storage=$storage drive=$drive");
276 my ($self, $fs) = @_;
278 my $out = $self->send_cmd("show fileset=\"$fs\"");
282 foreach my $l (split(/\r\n/, $out)) {
284 if ($l =~ /^\s+([I|E])\s+(.+)$/) { # include
285 push @{$ret->{$1}}, { file => $2 };
295 return split(/\r\n/, $self->send_cmd(".jobs"));
301 return split(/\r\n/, $self->send_cmd(".filesets"));
307 return split(/\r\n/, $self->send_cmd(".storage"));
313 return split(/\r\n/, $self->send_cmd(".clients"));
319 return split(/\r\n/, $self->send_cmd(".pools"));
322 use Time::ParseDate qw/parsedate/;
323 use POSIX qw/strftime/;
328 my ($self, @volume) = @_;
329 return '' unless (@volume);
332 foreach my $vol (@volume) {
333 if ($vol =~ /^([\w\d\.-]+)$/) {
334 $sel .= " volume=$1";
337 $self->{error} = "Sorry media is bad";
347 my ($self, @volume) = @_;
349 my $sel = $self->_get_volume(@volume);
352 $ret = $self->send_cmd("purge $sel");
354 $ret = $self->{error};
361 my ($self, @volume) = @_;
363 my $sel = $self->_get_volume(@volume);
366 $ret = $self->send_cmd_yes("prune $sel");
368 $ret = $self->{error};
375 my ($self, @jobid) = @_;
377 return 0 unless (@jobid);
380 foreach my $job (@jobid) {
381 if ($job =~ /^(\d+)$/) {
385 $self->{error} = "Sorry jobid is bad";
390 $self->send_cmd("purge $sel");
396 $self->send("quit\n");
397 $self->{bconsole}->soft_close();
398 $self->{bconsole} = undef;
406 # grep -v __END__ Bconsole.pm | perl
410 print "test sans conio\n";
412 my $c = new Bconsole(pref => {
413 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
417 print "fileset : ", join(',', $c->list_fileset()), "\n";
418 print "job : ", join(',', $c->list_job()), "\n";
419 print "storage : ", join(',', $c->list_storage()), "\n";
420 #print "prune : " . $c->prune_volume('000001'), "\n";
421 #print "update : " . $c->send_cmd('update slots storage=SDLT-1-2, drive=0'), "\n";
422 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
424 # drive => 0)), "\n";