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{debug} || 10,
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)) {
101 if ($self->{error}) {
105 unless ($self->{bconsole}) {
106 my @cmd = split(/\s+/, $self->{pref}->{bconsole}) ;
108 $self->{error} = "bconsole string not found";
111 $self->{bconsole} = new Expect;
112 $self->{bconsole}->raw_pty(0);
113 $self->{bconsole}->debug($self->{debug});
114 $self->{bconsole}->log_stdout($self->{debug} || $self->{log_stdout});
116 # WARNING : die is trapped by gtk_main_loop()
117 # and exit() closes DBI connection
120 my $sav = $SIG{__DIE__};
121 $SIG{__DIE__} = sub { _exit 1 ;};
122 $ret = $self->{bconsole}->spawn(@cmd) ;
123 $SIG{__DIE__} = $sav;
131 # TODO : we must verify that expect return the good value
133 $self->expect_it('*');
134 $self->send_cmd('gui on');
141 my ($self, $jobid) = @_;
142 return $self->send_cmd("cancel jobid=$jobid");
145 # get text between to expect
149 return $self->{bconsole}->before();
154 my ($self, $cmd) = @_;
155 unless ($self->connect()) {
158 $self->send("$cmd\n");
159 $self->expect_it($cmd);
160 $self->{bconsole}->clear_accum();
161 $self->expect_it('-re',qr/^[*]/);
162 return $self->before();
167 my ($self, $cmd) = @_;
168 unless ($self->connect()) {
171 $self->send("$cmd\n");
172 $self->expect_it('-re', '[?].+:');
174 $self->send("yes\n");
175 $self->expect_it("yes");
176 $self->{bconsole}->clear_accum();
177 $self->expect_it('-re',qr/^[*]/);
178 return $self->before();
181 sub send_cmd_with_drive
183 my ($self, $cmd, $drive) = @_;
184 $drive = $drive || '0';
186 unless ($self->connect()) {
189 $self->send("$cmd\n");
190 $self->expect_it('-re', '\[0\]\s*:');
192 $self->send("$drive\n");
193 $self->expect_it('-re', '[0-9]');
194 $self->{bconsole}->clear_accum();
195 $self->expect_it('-re',qr/^[*]/);
196 return $self->before();
201 my ($self, %arg) = @_;
203 unless ($arg{storage}) {
207 unless ($self->connect()) {
211 $arg{drive} = $arg{drive} || '0' ;
212 $arg{pool} = $arg{pool} || 'Scratch';
214 my $cmd = "label barcodes pool=\"$arg{pool}\" storage=\"$arg{storage}\"";
217 $cmd .= " slots=$arg{slots}";
220 $self->send("$cmd\n");
221 $self->expect_it('-re', '\[0\]\s*:');
222 $self->send("$arg{drive}\n");
223 $self->expect_it('-re', '[?].+\)\s*:');
224 my $res = $self->before();
225 $self->send("yes\n");
226 $self->expect_it("yes");
227 $res .= $self->before();
228 $self->expect_it('-re',qr/^[*]/);
229 $res .= $self->before();
234 # return [ { name => 'test1', vol => '00001', ... },
235 # { name => 'test2', vol => '00002', ... }... ]
237 sub director_get_sched
239 my ($self, $days) = @_ ;
243 unless ($self->connect()) {
247 my $status = $self->send_cmd("st director days=$days") ;
250 foreach my $l (split(/\r?\n/, $status)) {
251 #Level Type Pri Scheduled Name Volume
252 #Incremental Backup 11 03-ao-06 23:05 TEST_DATA 000001
253 if ($l =~ /^(I|F|Di)\w+\s+\w+\s+\d+/i) {
254 my ($level, $type, $pri, $d, $h, @name_vol) = split(/\s+/, $l);
256 my $vol = pop @name_vol; # last element
257 my $name = join(" ", @name_vol); # can contains space
275 my ($self, $storage, $drive) = @_;
277 return $self->send_cmd_with_drive("update slots storage=$storage", $drive);
283 return split(/\r\n/, $self->send_cmd(".jobs"));
289 return split(/\r\n/, $self->send_cmd(".filesets"));
295 return split(/\r\n/, $self->send_cmd(".storage"));
301 return split(/\r\n/, $self->send_cmd(".clients"));
304 use Time::ParseDate qw/parsedate/;
305 use POSIX qw/strftime/;
310 my ($self, @volume) = @_;
311 return '' unless (@volume);
314 foreach my $vol (@volume) {
315 if ($vol =~ /^([\w\d\.-]+)$/) {
316 $sel .= " volume=$1";
319 $self->{error} = "Sorry media is bad";
329 my ($self, @volume) = @_;
331 my $sel = $self->_get_volume(@volume);
334 $ret = $self->send_cmd("purge $sel");
336 $ret = $self->{error};
343 my ($self, @volume) = @_;
345 my $sel = $self->_get_volume(@volume);
348 $ret = $self->send_cmd_yes("prune $sel");
350 $ret = $self->{error};
357 my ($self, @jobid) = @_;
359 return 0 unless (@jobid);
362 foreach my $job (@jobid) {
363 if ($job =~ /^(\d+)$/) {
367 $self->{error} = "Sorry jobid is bad";
372 $self->send_cmd("purge $sel");
378 $self->send("quit\n");
379 $self->{bconsole}->soft_close();
380 $self->{bconsole} = undef;
388 # grep -v __END__ Bconsole.pm | perl
392 print "test sans conio\n";
394 my $c = new Bconsole(pref => {
395 bconsole => '/tmp/bacula/sbin/bconsole -n -c /tmp/bacula/etc/bconsole.conf',
399 print "fileset : ", join(',', $c->list_fileset()), "\n";
400 print "job : ", join(',', $c->list_job()), "\n";
401 print "storage : ", join(',', $c->list_storage()), "\n";
402 #print "prune : " . $c->prune_volume('000001'), "\n";
403 #print "update : " . $c->send_cmd_with_drive('update slots storage=SDLT-1-2'), "\n";
404 #print "label : ", join(',', $c->label_barcodes(storage => 'SDLT-1-2',
406 # drive => 0)), "\n";