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 drive=$arg{drive} pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
210 $cmd .= " slots=$arg{slots}";
213 $self->send("$cmd\n");
214 $self->expect_it('-re', '[?].+\)\s*:');
215 my $res = $self->before();
216 $self->send("yes\n");
217 $self->expect_it("yes");
218 $res .= $self->before();
219 $self->expect_it('-re',qr/^[*]/);
220 $res .= $self->before();
225 # return [ { name => 'test1', vol => '00001', ... },
226 # { name => 'test2', vol => '00002', ... }... ]
228 sub director_get_sched
230 my ($self, $days) = @_ ;
234 unless ($self->connect()) {
238 my $status = $self->send_cmd("st director days=$days") ;
241 foreach my $l (split(/\r?\n/, $status)) {
242 #Level Type Pri Scheduled Name Volume
243 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
244 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
245 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
247 my $vol = pop @name_vol; # last element
248 my $name = join(" ", @name_vol); # can contains space
266 my ($self, $storage, $drive) = @_;
267 $drive = $drive || 0;
269 return $self->send_cmd("update slots storage=$storage drive=$drive");
274 my ($self, $fs) = @_;
276 my $out = $self->send_cmd("show fileset=\"$fs\"");
280 foreach my $l (split(/\r\n/, $out)) {
282 if ($l =~ /^\s+([I|E])\s+(.+)$/) { # include
283 push @{$ret->{$1}}, { file => $2 };
293 return split(/\r\n/, $self->send_cmd(".jobs"));
299 return split(/\r\n/, $self->send_cmd(".filesets"));
305 return split(/\r\n/, $self->send_cmd(".storage"));
311 return split(/\r\n/, $self->send_cmd(".clients"));
317 return split(/\r\n/, $self->send_cmd(".pools"));
320 use Time::ParseDate qw/parsedate/;
321 use POSIX qw/strftime/;
326 my ($self, @volume) = @_;
327 return '' unless (@volume);
330 foreach my $vol (@volume) {
331 if ($vol =~ /^([\w\d\.-]+)$/) {
332 $sel .= " volume=$1";
335 $self->{error} = "Sorry media is bad";
345 my ($self, @volume) = @_;
347 my $sel = $self->_get_volume(@volume);
350 $ret = $self->send_cmd("purge $sel");
352 $ret = $self->{error};
359 my ($self, @volume) = @_;
361 my $sel = $self->_get_volume(@volume);
364 $ret = $self->send_cmd_yes("prune $sel");
366 $ret = $self->{error};
373 my ($self, @jobid) = @_;
375 return 0 unless (@jobid);
378 foreach my $job (@jobid) {
379 if ($job =~ /^(\d+)$/) {
383 $self->{error} = "Sorry jobid is bad";
388 $self->send_cmd("purge $sel");
394 $self->send("quit\n");
395 $self->{bconsole}->soft_close();
396 $self->{bconsole} = undef;
404 # grep -v __END__ Bconsole.pm | perl
408 print "test sans conio\n";
410 my $c = new Bconsole(pref => {
411 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
415 print "fileset : ", join(',', $c->list_fileset()), "\n";
416 print "job : ", join(',', $c->list_job()), "\n";
417 print "storage : ", join(',', $c->list_storage()), "\n";
418 #print "prune : " . $c->prune_volume('000001'), "\n";
419 #print "update : " . $c->send_cmd('update slots storage=SDLT-1-2, drive=0'), "\n";
420 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
422 # drive => 0)), "\n";