Imported Upstream version 3.3.3
[debian/amanda] / perl / Amanda / Script_App.pm
1 # vim:ft=perl
2 # Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 # for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
19 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
20
21 package Amanda::Script_App;
22
23 no warnings;
24 no strict;
25 $GOOD  = 0;
26 $ERROR = 1;
27 $FAILURE = 2;
28
29 use strict;
30 use warnings;
31 use Amanda::Constants;
32 use Amanda::Config qw( :init :getconf  config_dir_relative );
33 use Amanda::Debug qw( :logging );
34 use Amanda::Paths;
35 use Amanda::Util qw( :constants );
36 use Carp;
37
38 =head1 NAME
39
40 Amanda::Script_App - perl utility functions for Scripts.
41
42 =head1 SYNOPSIS
43
44 This module should not be used directly. Instead, use C<Amanda::Application> or
45 C<Amanda::Script>.
46
47 =cut
48
49 sub new {
50     my $class = shift;
51     my ($execute_where, $type, $config_name) = @_;
52
53     my $self = {};
54     bless ($self, $class);
55
56     # extract the last component of the class name
57     my $name = $class;
58     $name =~ s/^.*:://;
59     $self->{'name'} = $name;
60
61     if(!defined $execute_where) {
62         $execute_where = "client";
63     }
64     Amanda::Util::setup_application($name, $execute_where, $CONTEXT_DAEMON);
65     debug("Arguments: " . join(' ', @ARGV));
66
67     #initialize config client to get values from amanda-client.conf
68     config_init($CONFIG_INIT_CLIENT, undef);
69     my ($cfgerr_level, @cfgerr_errors) = config_errors();
70     if ($cfgerr_level >= $CFGERR_WARNINGS) {
71         config_print_errors();
72         if ($cfgerr_level >= $CFGERR_ERRORS) {
73             confess("errors processing config file");
74         }
75     }
76     if ($config_name) {
77         config_init($CONFIG_INIT_CLIENT | $CONFIG_INIT_EXPLICIT_NAME | $CONFIG_INIT_OVERLAY, $config_name);
78         ($cfgerr_level, @cfgerr_errors) = config_errors();
79         if ($cfgerr_level >= $CFGERR_WARNINGS) {
80             config_print_errors();
81             if ($cfgerr_level >= $CFGERR_ERRORS) {
82                 confess("errors processing config file for $config_name");
83             }
84         }
85     }
86
87     Amanda::Util::finish_setup($RUNNING_AS_ANY);
88
89     $self->{error_status} = $Amanda::Script_App::GOOD;
90     $self->{type} = $type;
91     $self->{known_commands} = {};
92
93     debug("$type: $name\n");
94
95     return $self;
96 }
97
98
99 #$_[0] message
100 #$_[1] status: GOOD or ERROR
101 sub print_to_server {
102     my $self = shift;
103     my($msg, $status) = @_;
104     if ($status != 0) {
105         $self->{error_status} = $status;
106     }
107     if ($self->{action} eq "check") {
108         if ($status == $Amanda::Script_App::GOOD) {
109             print STDOUT "OK $msg\n";
110         } else {
111             print STDOUT "ERROR $msg\n";
112         }
113     } elsif ($self->{action} eq "estimate") {
114         if ($status == $Amanda::Script_App::GOOD) {
115             #do nothing
116         } else {
117             print STDERR "ERROR $msg\n";
118         }
119     } elsif ($self->{action} eq "backup") {
120         if ($status == $Amanda::Script_App::GOOD) {
121             print {$self->{mesgout}} "| $msg\n";
122         } elsif ($status == $Amanda::Script_App::ERROR) {
123             print {$self->{mesgout}} "? $msg\n";
124         } else {
125             print {$self->{mesgout}} "sendbackup: error $msg\n";
126         }
127     } elsif ($self->{action} eq "restore") {
128         print STDERR "$msg\n";
129     } elsif ($self->{action} eq "validate") {
130         print STDERR "$msg\n";
131     } else {
132         print STDERR "$msg\n";
133     }
134 }
135
136 #$_[0] message
137 #$_[1] status: GOOD or ERROR
138 sub print_to_server_and_die {
139     my $self = shift;
140
141     $self->print_to_server( @_ );
142     if (!defined $self->{die} && $self->can("check_for_backup_failure")) {
143         $self->{die} = 1;
144         $self->check_for_backup_failure();
145     }
146     exit 1;
147 }
148
149
150 sub do {
151     my $self = shift;
152     my $command  = shift;
153
154     if (!defined $command) {
155         $self->print_to_server_and_die("check", "no command",
156                                        $Amanda::Script_App::ERROR);
157         return;
158     }
159     $command =~ tr/A-Z-/a-z_/;
160     debug("command: $command");
161
162     # first make sure this is a valid command.
163     if (!exists($self->{known_commands}->{$command})) {
164         print STDERR "Unknown command `$command'.\n";
165         exit 1;
166     }
167
168     my $action = $command;
169     $action =~ s/^pre_//;
170     $action =~ s/^post_//;
171     $action =~ s/^inter_//;
172     $action =~ s/^dle_//;
173     $action =~ s/^host_//;
174     $action =~ s/^level_//;
175
176     if ($action eq 'amcheck' || $action eq 'selfcheck') {
177         $self->{action} = 'check';
178     } elsif ($action eq 'estimate') {
179         $self->{action} = 'estimate';
180     } elsif ($action eq 'backup') {
181         $self->{action} = 'backup';
182     } elsif ($action eq 'recover' || $action eq 'restore') {
183         $self->{action} = 'restore';
184     } elsif ($action eq 'validate') {
185         $self->{action} = 'validate';
186     }
187
188     if ($action eq 'backup') {
189         $self->_set_mesgout();
190     }
191
192     # now convert it to a function name and see if it's
193     # defined
194     my $function_name = "command_$command";
195     my $default_name = "default_$command";
196
197     if (!$self->can($function_name)) {
198         if (!$self->can($default_name)) {
199             print STDERR "command `$command' is not supported by the '" .
200                          $self->{name} . "' " . $self->{type} . ".\n";
201             exit 1;
202         }
203         $self->$default_name();
204         return;
205     }
206
207     # it exists -- call it
208     $self->$function_name();
209 }
210
211 1;