Imported Upstream version 3.3.3
[debian/amanda] / perl / Amanda / Interactivity.pm
1 # Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 # for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19
20 package Amanda::Interactivity;
21
22 =head1 NAME
23
24 Amanda::Interactivity -- Parent class for user interactivity modules
25
26 =head1 SYNOPSIS
27
28     use Amanda::Interactivity;
29
30     my $inter = Amanda::Interactivity->new(name => 'stdin');
31     $inter->user_request(
32         message => "Insert Volume labelled 'MY_LABEL-001' in changer DLT",
33         label => 'MY_LABEL-001',
34         new_volume => 0,
35         chg_name => 'DLT',
36         err => "Not found in the library",
37         request_cb => sub {
38             my ($err, $reply) = @_;
39             if ($err) {
40                 # error from the script
41             } elsif (!defined $reply) {
42                 # request aborted
43             } else {
44                 # use reply
45             }
46         });
47
48 =head1 SUMMARY
49
50 This package provides a way for Amanda programs to communicate interactivityly
51 with the user.  The program can send a message to the user and await a textual
52 response.  The package operates asynchronously (see L<Amanda::MainLoop>), so
53 the program may continue with other activities while waiting for an answer from
54 the user.
55
56 Several interactivity modules are (or soon will be) available, and can be
57 selected by the user.
58
59 =head1 INTERFACE
60
61 A new object is create with the C<new> function as follows:
62
63     my $inter = Amanda::Interactivity->new(
64         name => $interactivity_name);
65
66 Where C<$interactivity_name> is the name of the desired interactivity defined
67 in the config file.
68
69 =head2 INTERACTIVITY OBJECTS
70
71 =head3 user_request
72
73   $inter->user_request(message     => $message,
74                        label       => $label,
75                        new_volume  => 0|1,
76                        err         => $err,
77                        chg_name    => $chg_name,
78                        request_cb  => $request_cb);
79
80 This method return immediately.  It sends a message to the user and waits for a
81 reply.
82  C<err> is the reason why the volume is needed.
83  C<message> is a sentence describing the requested volume.
84  The volume can be describe with many parameters:
85   C<label> is the requested label or the most prefered label.
86   C<new_volume> if a new volume is acceptable.
87   C<chg_name> the name of the changer where amanda expect the volume.
88
89 A module can print only C<message> or build something prettier with the values
90 of the other parameters.
91
92 The C<request_cb> callback take one or two arguments.  In the even of an
93 error, it is called with an C<Amanda::Changer::Error> object as first argument.
94 If the request is answered, then the first argument is C<undef> and the second
95 argument is the user's response.  If the request is aborted (see C<abort>,
96 below), then both arguments are C<undef>.
97
98 =head3 abort
99
100   $inter->abort()
101
102 This method will abort all pending C<user_request> invocations, invoking their
103 C<request_cb> with C<(undef, undef)>.
104
105 =cut
106
107 use Amanda::Config qw( :getconf );
108
109 sub new {
110     shift eq 'Amanda::Interactivity'
111         or return;
112     my %params = @_;
113     my $interactivity_name = $params{'name'};
114
115     return undef if !defined $interactivity_name or $interactivity_name eq '';
116
117     my $interactivity = Amanda::Config::lookup_interactivity($interactivity_name);
118     my $plugin;
119     my $property;
120     if ($interactivity) {
121         $plugin = Amanda::Config::interactivity_getconf($interactivity, $INTERACTIVITY_PLUGIN);
122         $property = Amanda::Config::interactivity_getconf($interactivity, $INTERACTIVITY_PROPERTY);
123     } else {
124         $plugin = $interactivity_name;
125     }
126
127     die("No name for Amanda::Interactivity->(new)") if !defined $plugin;
128
129     my $pkgname = "Amanda::Interactivity::$plugin";
130     my $filename = $pkgname;
131     $filename =~ s|::|/|g;
132     $filename .= '.pm';
133
134     if (!exists $INC{$filename}) {
135         eval "use $pkgname;";
136         if ($@) {
137             my $err = $@;
138             die ($err);
139         }
140     }
141
142     my $self = eval {$pkgname->new($property);};
143     if ($@ || !defined $self) {
144         print STDERR "Can't instantiate $pkgname\n";
145         debug("Can't instantiate $pkgname");
146         die("Can't instantiate $pkgname");
147     }
148
149     return $self;
150 }
151
152 1;