3c53a8811697e031270f92130d73a84756709c99
[debian/amanda] / server-src / amserverconfig.pl
1 #!@PERL@
2 #
3 # Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License version 2 as published
7 # by the Free Software Foundation.
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 94086, USA, or: http://www.zmanda.com
20 #
21
22 use lib '@amperldir@';
23 use Getopt::Long;
24 use Time::Local;
25 use File::Copy;
26 use File::Path;
27 use Socket;   # for gethostbyname
28 use Amanda::Paths;
29 use Amanda::Util qw( :constants );
30 use Amanda::Constants;
31
32 my $confdir="$CONFIG_DIR";
33 my $tmpdir="$AMANDA_DBGDIR";
34 my $amandahomedir="$localstatedir/lib/amanda";
35 my $templatedir="$amdatadir/template.d"; #rpm install template files here
36 my $def_tapedev="file:$amandahomedir/vtapes";
37
38 my $amanda_user="$Amanda::Constants::CLIENT_LOGIN";
39 my $def_config="$Amanda::Constants::DEFAULT_CONFIG";
40 my $def_dtimeout="1800";
41 my $def_ctimeout="30";
42 my $def_etimeout="300";
43 my $def_perm=0750;
44 my $amanda_conf_perm=0600;
45 my $def_tapecycle=10;
46 my $config;
47 my $vtape_err=0;
48 my $holding_err=0;
49 my $template_only=0;
50 my $parentdir;
51 my $host;
52 my @pw = getpwuid($<);
53 my $dumpuser = $pw[0];
54
55
56 #usage
57 sub usage {
58         print "$0\n";
59         print "\t\t <config> [--template <template>]\n";
60         print "\t\t[--no-vtape] (do not create virtual tapes)\n";
61         print "\t\t[--tapetype <tapetype>] [--tpchanger <tpchanger>]\n";
62         print "\t\t[--tapedev <tapedev>] [--changerfile <changerfile>]\n";
63         print "\t\t[--changerdev <changerdev>] [--labelstr <labelstr>] \n";
64         print "\t\t[--mailto <mailto>] [--dumpcycle <dumpcycle> (ex: 5days, 1week or 2weeks)]\n";
65         print "\t\t[--runspercycle <runspercycle>] [--runtapes <runtapes>]\n";
66         print "\t\t[--tapecycle <tapecycle>]\n";
67         print "\t\t[--help]\n";
68 }
69
70 #print and log
71 sub mprint {
72     for $fh ( STDOUT, LOG ) {
73         print $fh @_;
74     }
75 }
76
77 sub log_and_die { 
78     my ($err, $cleanup) = @_;
79     print LOG $err;
80     # clean up $config directory if cleanup=1
81     # if error in creating vtape or holding disk, 
82     # advise user to create manually, no need to cleanup
83     if ( $cleanup && defined $config  && -e "$confdir/$config" ) {
84         print LOG "cleaning up $confdir/$config\n";
85         if ( -e "$confdir/$config/amanda.conf" ) {
86             unlink "$confdir/$config/amanda.conf" || 
87             print LOG "unlink $confdir/$config/amanda.conf failed: $!\n";
88         }
89         if ( -e "$confdir/$config/advanced.conf" ) {
90             unlink "$confdir/$config/advanced.conf" || 
91             print LOG "unlink $confdir/$config/advanced.conf failed: $!\n";
92         }
93         if ( -e "$confdir/$config/tapelist" ) {
94             unlink "$confdir/$config/tapelist" || 
95             print LOG "unlink $confdir/$config/tapelist failed: $!\n";
96         }
97         if ( -e "$confdir/$config/curinfo" ) {
98             rmdir "$confdir/$config/curinfo" || 
99             print LOG "rmdir $confdir/$config failed: $!\n";
100         }
101         if ( -e "$confdir/$config/index" ) {
102             rmdir "$confdir/$config/index" || 
103             print LOG "rmdir $confdir/$config/index failed: $!\n";
104         }
105         rmdir "$confdir/$config" || 
106             print LOG "rmdir $confdir/$config failed: $!\n";
107     }
108     die $err;
109 }
110
111
112 # rpm installation should have taken care of these. Create one if it's not there
113 sub check_gnutarlist_dir {
114     if ( -e "$amandahomedir/gnutar-lists" ) {
115         &mprint ("$amandahomedir/gnutar-lists directory exists\n");
116     }
117     else {
118         mkpath ("$amandahomedir/gnutar-lists", $def_perm) ||
119             &log_and_die ("ERROR: mkpath:$amandahomedir/gnutar-lists failed: $!\n", 0);
120     }
121 }
122
123 sub create_conf_dir {
124   unless ( -e "$confdir/$config" ) {
125     mkpath ("$confdir/$config", $def_perm) ||
126       &log_and_die ("ERROR: mkpath: $confdir/$config failed: $!\n", 0); # $! = system error
127   } else {
128     &log_and_die ("ERROR: Configuration $config exists\n", 0);
129   }
130   unless ( -e "$confdir/template.d" ) {
131     mkpath ("$confdir/template.d", $def_perm)  ||
132       &log_and_die ("ERROR: mkpath: $confdir/template.d failed: $!\n", 0);
133     &mprint ("$confdir/template.d directory created\n");
134   }
135 }
136
137 sub copy_template_file {
138     my $tplate = $_[0];
139     unless ($tplate) {
140         &log_and_die ("ERROR: template is missing\n", 1);
141     }
142     # create and update amanda.conf
143     open(CONF, "$templatedir/amanda-$tplate.conf")
144         || &log_and_die ("ERROR: Cannot open $templatedir/amanda-$tplate.conf: $!\n", 1);
145     open(NEWCONF, ">$confdir/$config/amanda.conf") ||
146         &log_and_die ("ERROR: Cannot create $confdir/$config/amanda.conf: $!\n", 1);
147     chmod ($amanda_conf_perm, "$confdir/$config/amanda.conf") ||
148         &log_and_die ("ERROR: Cannot set amanda.conf file access permission: $!\n", 1);
149     while (<CONF>) {
150         $_ =~ s/$def_config/$config/;
151         print NEWCONF $_;
152     }
153     close(CONF);
154     close(NEWCONF);
155     &mprint ("$confdir/$config/amanda.conf created and updated\n");
156 }
157
158
159 sub create_curinfo_index_dir {
160     mkpath("$confdir/$config/curinfo", $def_perm) ||
161         &log_and_die ("ERROR: mkpath: $confdir/$config/curinfo failed: $!\n", 1);
162     mkpath("$confdir/$config/index", $def_perm) || 
163         &log_and_die ("ERROR: mkpath: $confdir/$config/index failed: $!\n", 1);
164     &mprint ("curinfo and index directory created\n");
165 }
166
167 sub touch_list_files {
168     open (TLIST, ">$confdir/$config/tapelist")
169         || &log_and_die ("ERROR: Cannot create tapelist file: $!\n", 1);
170     close (TLIST);
171     &mprint ("tapelist file created\n");
172
173     open (DLIST, ">$confdir/$config/disklist")
174         || &log_and_die ("ERROR: Cannot create disklist file: $!\n", 1);
175     close (DLIST);
176     &mprint ("disklist file created\n");
177 }
178
179 # create holding disk directory, check disk space first
180 sub create_holding { 
181   if ( -d "$amandahomedir/holdings/$config" ) {
182     my $uid = (stat("$amandahomedir/holdings/$config"))[4];
183     my $owner = (getpwuid($uid))[0];
184     unless ( $owner eq $amanda_user ) {
185       &mprint ("WARNING: holding disk directory exists and is not owned by $amanda_user\n");
186       $holding_err++;
187     }
188     return;
189   }
190     my $div=1;
191     my $out = `df -k $amandahomedir`;
192     my @dfout = split(" " , $out);
193     unless ( $#dfout == 12 ) {  # df should output 12 elem
194         &mprint ("WARNING: df failed, holding disk directory not created\n");
195         $holding_err++;
196         return;
197     }
198     unless (( $dfout[1] eq "1K-blocks" ) || ( $dfout[1] eq "kbytes")) {
199          $div=2;        # 512-blocks displayed by df
200      }
201     
202     if (( $dfout[10] / $div )  > 1024000 ) { # holding disk is defined 1000 MB
203         &mprint ("creating holding disk directory\n");
204         unless ( -d "$amandahomedir/holdings" ) { 
205         mkpath ( "$amandahomedir/holdings", $def_perm) ||
206             (&mprint ("WARNING: mkpath $amandahomedir/holdings failed: $!\n"), $holding_err++, return );
207     }
208         mkpath ( "$amandahomedir/holdings/$config", $def_perm) ||
209             (&mprint ("WARNING: mkpath $amandahomedir/holdings/$config failed: $!\n"), $holding_err++, return) ;
210     }
211 }
212
213 #create default tape dir
214 sub create_deftapedir{
215     unless ( -e "$amandahomedir/vtapes" ) { 
216         mkpath ( "$amandahomedir/vtapes", $def_perm) ||
217             ( &mprint ("WARNING: mkpath $amandahomedir/$config/vtapes failed: $!\n"), return );
218     }
219     unless ( -e "$amandahomedir/vtapes/$config" ) { 
220         mkpath ( "$amandahomedir/vtapes/$config", $def_perm) ||
221             ( &mprint ("WARNING: mkpath $amandahomedir/vtapes/$config failed: $!\n"), return );
222     }
223         $parentdir="$amandahomedir/vtapes/$config";
224 }
225
226 # create and label vtape
227 sub create_vtape {
228         &mprint ("creating vtape directory\n");
229         if ($template_only==0){ #  check $template mode
230                 $mylabelprefix=$labelstr;   #set labelstr
231                 if ($tapedev eq "$def_tapedev/$config"){
232                     &create_deftapedir;
233                 }
234                 else {
235                     $parentdir=$tapedev;
236                 }
237         }
238         else {
239                 $mylabelprefix=$config;
240                 &create_deftapedir;     
241         }
242         unless ( -e $parentdir){
243                 &mprint ("WARNING: tapedev $parentdir does not exists, vtapes creation failed!\n");
244                 &mprint ("Please create $parentdir and $confdir/$config and rerun the same command or else create vtapes manually.\n");
245                 $vtape_err++;
246                 return;
247         }
248
249         chdir ("$parentdir") ||
250                 ( &mprint("WARNING: chdir $parentdir failed: $!\n"), $vtape_err++, return );
251     my $i;
252     &mprint ("amlabel vtapes\n");
253         if (defined $tapecycle) {
254                 $tapecycle=~/^\d+/; 
255                 $tp_cyclelimit=$&;
256
257                 # check space
258                 my $fsinfo = Amanda::Util::get_fs_usage($parentdir);
259                 my $avail_bytes = $fsinfo->{'blocksize'} * $fsinfo->{'bavail'};
260
261                 # mysteriously, we need at least 72k per slot, plus 10k overhead.  The
262                 # origin of these numbers is unknown.
263                 my $needed_bytes = (($tp_cyclelimit*73728)+10240);
264                 if ($avail_bytes < $needed_bytes){
265                         &mprint ("WARNING: Not enough space for vtapes. Need 72k per slot plus 10k ($needed_bytes bytes); have $avail_bytes available.  Creation of vtapes failed\n");
266                         $vtape_err++;
267                         return;
268                 }
269         }
270         else {
271                 $tp_cyclelimit=$def_tapecycle;
272         }
273
274         for $i (1..$tp_cyclelimit) {
275                 unless ( -e "slot$i"){
276                     mkpath ("slot$i", $def_perm) ||
277                     ( &mprint ("WARNING: mkpath $parentdir/slot$i failed: $!\n"), $vtape_err++, return);
278                 }
279                 ( @amlabel_out = `$sbindir/amlabel -f $config $mylabelprefix-$i slot $i`) ||
280                 ( &mprint ("WARNING: amlabel vtapes failed at slot $i: $!\n"), $vtape_err++, return);
281     }
282         foreach (@amlabel_out) {
283           print LOG;
284         }
285         # reset tape to the first slot
286         `$sbindir/amtape $config reset`;
287 }
288
289 sub create_customconf{
290            # now create a custom amanda.conf from user input
291         unless ( $mailto ) 
292         { $mailto="$amanda_user"; }
293         else {  # untaint mailto which can be evil
294                 # reject mailto with the following * ( ) < > [ ] , ; : ! $ \ / "
295             if ( $mailto =~ /^([^\*\(\)<>\[\]\,\;\:\!\$\\\/\"]+)$/ ) {
296                 $mailto = $1;                      #  now untainted
297             } else {
298                 &log_and_die ("ERROR: Invalid data in mailto.\n");  # log this somewhere
299             }
300         }
301         unless ( $dumpcycle ) { $dumpcycle="1 week"; }
302         unless ( $runspercycle ) { $runspercycle="5"; }
303         unless ( $tapecycle ) { $tapecycle="10 tapes"; }
304         unless ( $runtapes ) { $runtapes="1"; }
305         unless ( $labelstr ) {
306           if ($template eq "harddisk") {
307             $labelstr="$config";
308           } else {
309             $labelstr="^$config-[0-9][0-9]*\$";
310           }
311         }
312
313         open (CONF, ">$confdir/$config/amanda.conf") ||
314             &log_and_die ("ERROR: Cannot create amanda.conf file: $!\n", 1);
315         chmod ($amanda_conf_perm, "$confdir/$config/amanda.conf") ||
316             &log_and_die ("ERROR: Cannot set amanda.conf file access permission: $!\n", 1);
317
318         print CONF "org \"$config\"\t\t# your organization name for reports\n";
319         print CONF "dumpuser \"$dumpuser\"\t# the user to run dumps under\n";
320         print CONF "mailto \"$mailto\"\t# space separated list of operators at your site\n";
321         print CONF "dumpcycle $dumpcycle\t\t# the number of days in the normal dump cycle\n";
322         print CONF "runspercycle $runspercycle\t\t# the number of amdump runs in dumpcycle days\n";
323         print CONF "tapecycle $tapecycle\t# the number of tapes in rotation\n";
324         print CONF "runtapes $runtapes\t\t# number of tapes to be used in a single run of amdump\n";
325
326         if ((!(defined($template)))||($template eq "harddisk")) 
327           {
328                 print CONF "\n";
329                 print CONF "define changer my_vtapes {\n";
330                 print CONF "    tpchanger \"chg-disk:$tapedev\"\n";
331                 print CONF "    property \"num-slot\" \"10\"\n";
332                 print CONF "    property \"auto-create-slot\" \"yes\"\n";
333                 print CONF "}\n";
334                 print CONF "tpchanger \"my_vtapes\"\n\n";
335                 unless ( $tapetype ) { $tapetype="HARDDISK"; }  
336           }
337         elsif ($template eq "single-tape")
338           {
339                 print CONF "\n";
340                 print CONF "define changer my_single {\n";
341                 print CONF "    tpchanger \"chg-single:$tapedev\"\n";
342                 print CONF "}\n";
343                 print CONF "tpchanger \"my_single\"\n\n";
344                 unless ($tapetype) {$tapetype="HP-DAT";}
345           }
346         elsif ($template eq "tape-changer") 
347           {
348                 print CONF "\n";
349                 print CONF "define changer my_robot {\n";
350                 print CONF "    tpchanger \"chg-robot:$changerdev\"\n";
351                 print CONF "    property \"tape-device\" \"0=$tapedev\"\n";
352                 print CONF "}\n";
353                 print CONF "tpchanger \"my_robot\"\n\n";
354                 unless ($tapetype)  {$tapetype="HP-DAT";}
355           }
356         else # S3 case
357           {
358                 print CONF "\n";
359                 print CONF "define changer my_s3 {\n";
360                 print CONF "    tpchanger \"chg-multi:$tapedev\"\n";
361                 print CONF "    device-property \"S3_ACCESS_KEY\" \"\"\n";
362                 print CONF "    device-property \"S3_SECRET_KEY\" \"\"\n";
363                 print CONF "    device-property \"NB_THREADS_BACKUP\" \"\"\n";
364                 print CONF "}\n";
365                 print CONF "tpchanger \"my_s3\"\n\n";
366             unless ($tapetype)  {$tapetype="HP-DAT";}
367           }
368
369         print CONF "tapetype $tapetype\t# what kind of tape it is\n";
370         print CONF "labelstr \"$labelstr\"\t# label constraint regex: all tapes must match\n";
371         print CONF "dtimeout $def_dtimeout\t# number of idle seconds before a dump is aborted\n";
372         print CONF "ctimeout $def_ctimeout\t# max number of secconds amcheck waits for each client\n";
373         print CONF "etimeout $def_etimeout\t# number of seconds per filesystem for estimates\n";
374         print CONF "define dumptype global {\n";
375         print CONF "       comment \"Global definitions\"\n";
376         print CONF "       auth \"bsdtcp\"\n}\n";
377         print CONF "define dumptype gui-base {\n";
378         print CONF "       global\n";
379         print CONF "       program \"GNUTAR\"\n";
380         print CONF "       comment \"gui base dumptype dumped with tar\"\n";
381         print CONF "       compress none\n";
382         print CONF "       index yes\n}\n";
383         if ($tapetype eq "HARDDISK") {
384           print CONF "define tapetype HARDDISK {\n";
385           print CONF "       comment \"Virtual Tapes\"\n";
386           print CONF "       length 5000 mbytes\n}\n";
387         }
388         print CONF "includefile \"advanced.conf\"\n";
389         print CONF "includefile \"$confdir/template.d/dumptypes\"\n";
390         print CONF "includefile \"$confdir/template.d/tapetypes\"\n";
391         close (CONF);
392         mprint ("custom amanda.conf created\n");
393   }
394
395
396 sub check_xinetd{
397     &mprint ("/var/lib/amanda/example/xinetd.amandaserver contains the latest Amanda server daemon configuration.\n");
398     &mprint ("Please merge it to /etc/xinetd.d/amandaserver.\n");
399 }
400
401
402 sub build_amanda_ssh_key{
403   if ( -e "$amandahomedir/.ssh/id_rsa_amdump.pub" ) {
404     if ( -e "$amandahomedir/.ssh/client_authorized_key" ) {
405       &mprint ("$amandahomedir/.ssh/client_authorized_keys exists.\n");
406     }
407     else {
408       open(NEWAUTH, ">$amandahomedir/.ssh/client_authorized_keys") ||
409         (&mprint("WARNING: open $amandahomedir/.ssh/client_authorized_key failed: $!\n"), return);
410       open(PUB, "$amandahomedir/.ssh/id_rsa_amdump.pub") ||
411         (&mprint("WARNING: open $amandahomedir/.ssh/id_rsa_amdump.pub failed: $!\n"), return);
412       print NEWAUTH "from=\"$host\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=\"/usr/lib/amanda/amandad -auth=ssh amdump\" ";
413       while (<PUB>) {
414       print NEWAUTH;
415     }
416       close NEWAUTH;
417       close PUB;
418       &mprint("$amandahomedir/.ssh/client_authorized_keys created. Please append to $amandahomedir/.ssh/authorized_keys file on Amanda clients\n");
419       }
420   }
421 }
422
423 sub copy_chg_manual_conf {
424   if ( $template eq "single-tape" && !defined $changerfile && !defined $tpchanger)
425     {
426       my $my_changerfile="$confdir/$config/chg-manual.conf";
427       copy("$templatedir/chg-manual.conf", $my_changerfile) ||
428         &mprint ("copy $templatedir/chg-manual.conf to $my_changerfile failed: $!\n");
429     }
430 }
431
432 #main
433 my $ret=0;
434
435 $ret = GetOptions ("template=s"=>\$template,
436                    "no-vtape!"=>\$novtape,
437               "tapetype=s"=>\$tapetype,
438               "tpchanger=s"=>\$tpchanger,
439               "tapedev=s"=>\$tapedev,
440               "changerfile=s"=>\$changerfile,
441               "changerdev=s"=>\$changerdev,
442               "labelstr=s"=>\$labelstr,
443               "mailto=s"=>\$mailto,
444               "dumpcycle=s"=>\$dumpcycle,
445               "runspercycle=i"=>\$runspercycle,
446               "runtapes=i"=>\$runtapes,
447               "tapecycle=i"=>\$tapecycle,
448               "help!"=>\$help
449               );
450
451 unless ( $ret ) {
452     &usage;
453     exit 1;
454 }
455
456 if($help) {
457     &usage;
458     exit 0;
459 }
460
461 unless ( $#ARGV == 0 ) {
462     print STDERR "ERROR: config name is required.\n";
463     &usage;
464     exit 1;
465 }
466 else {
467     if ( "$ARGV[0]" =~ /^([-\@\w.]+)$/ ) {
468         $config = $1;                   #  now untainted
469     } else {
470         die ("ERROR: Invalid data in config name.\n");  # log this somewhere
471     }
472 }
473
474
475 $oldPATH = $ENV{'PATH'};
476
477 $ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin:/usr/ucb"; # force known path
478 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
479 $date=`date +%Y%m%d%H%M%S`;
480 chomp($date);
481 my $logfile="$tmpdir/amserverconfig.$date.debug";
482
483 Amanda::Util::setup_application("amserverconfig", "server", $CONTEXT_CMDLINE);
484 Amanda::Util::finish_setup($RUNNING_AS_ANY);
485
486 unless ( -e "$tmpdir" ) {
487     mkpath ("$tmpdir", $def_perm) ||
488         die ("ERROR: mkpath: $tmpdir failed: $!\n");
489 }
490
491 open (LOG, ">$logfile") || die ("ERROR: Cannot create logfile: $!\n");
492 print STDOUT "Logging to $logfile\n";
493
494 my $lhost=`hostname`;
495 chomp($lhost);
496 # get our own canonical name, if possible (we don't sweat the IPv6 stuff here)
497 $host=(gethostbyname($lhost))[0];
498
499 unless ( $host ) {
500     $host = $lhost;  #gethostbyname() failed, go with hostname output
501 }
502
503
504 my $need_changer = 0;
505 if ( defined $template ) {
506
507     # validate user input to template
508     chomp($template);
509     my $found = 0;
510     @valid_templates = ( "harddisk", "single-tape", "tape-changer", "s3" );
511     foreach $elt (@valid_templates) {
512         if ( $elt eq lc($template) ) {
513             $found = 1;
514             last;
515         }
516     }
517     unless ($found) {
518         print STDERR
519             "valid inputs to --templates are harddisk, single-tape, tape-changer or S3\n";
520         &usage;
521         exit 1;
522     }
523
524     # if tape-changer is chosen, check if mtx is installed
525     if ( $template eq "tape-changer" ) {
526         my $ok = 0;
527         for $dir ( "/usr/sbin", "/usr/local/sbin", "/usr/local/bin",
528             "/usr/bin", "/bin", "/opt/csw/sbin", split( ":", $oldPATH ) )
529         {
530             if ( -e "$dir/mtx" ) {
531                 $ok = 1;
532                 last;
533             }
534         }
535         unless ($ok) {
536             &mprint(
537                 "ERROR: mtx binary not found, tape-changer template will not work and is not installed.\n"
538             );
539             &log_and_die(
540                 "ERROR: Please install mtx and rerun the same command.\n",
541                 0 );
542         }
543         $need_changer = 1;
544     }
545     elsif ( $template eq "S3" ) {
546         $need_changer = 1;
547     }
548
549 }
550
551 &create_conf_dir;
552
553 if ($need_changer) {
554     unless ($changerfile) {
555         $changerfile = "$confdir/$config/changer.conf";
556     }
557     open( CCONF, ">$changerfile" )
558         || &log_and_die( "ERROR: Cannot create $changerfile: $!\n", 1 );
559     close(CCONF);
560 }
561
562 &check_gnutarlist_dir;
563
564 # copy dumptypes and tapetypes files if none exists.
565 my $dtype="$confdir/template.d/dumptypes";
566 my $ttype="$confdir/template.d/tapetypes";
567
568 unless ( -e $dtype ) {
569     copy("$templatedir/dumptypes", $dtype ) ||
570     &log_and_die ("ERROR: copy dumptypes failed: $!\n", 1);
571 }
572
573
574 unless ( -e $ttype ) {
575     copy("$templatedir/tapetypes", $ttype ) ||
576     &log_and_die ("ERROR: copy tapetypes file to $ttype failed: $!\n", 1);
577 }
578
579
580
581 # update $def_config value to the specified config value in advanced.conf
582     open(ADV, "$templatedir/advanced.conf") || &log_and_die ("ERROR: Cannot open advanced.conf file: $!\n", 1);
583     open(NEWADV, ">$confdir/$config/advanced.conf") || 
584         &log_and_die ("ERROR: Cannot create advanced.conf file: $!\n", 1);
585     while (<ADV>) {
586         $_ =~ s/$def_config/$config/;
587         print NEWADV $_;
588     }
589     close(ADV);
590     close(NEWADV);
591     &mprint ("$confdir/$config/advanced.conf created and updated\n");
592
593
594 &create_curinfo_index_dir;
595 &touch_list_files;
596
597
598 if ( defined $template ) {
599 # if any other parameters are provided, create a workable custom config
600         if ( defined $tapetype || defined $tpchanger || defined $tapedev
601          || defined $changerdev || defined $labelstr || defined $mailto || defined $dumpcycle
602          || defined $runspercycle || defined $runtapes || defined $tapecycle ) {
603                 &mprint("Creating custom configuration using templates\n");
604                 create_customconf();
605                 if ( $template ne "harddisk" ) {
606                   &create_holding;
607                 } else {
608                   if (defined $labelstr) {
609                     if ($labelstr=~/^([-\w.]+)$/) {
610                       &create_vtape unless ( defined $novtape );
611                     } else {
612                       &mprint ("WARNING: Only alphanumeric string is supported in labelstr when using template to create vtapes. ");
613                       &mprint ("If you want to use regex in labelstr, please create vtapes manually.\n");
614                     }
615                   }
616                 }
617               } else {
618                 $template_only=1;
619                 $tapedev="$def_tapedev/$config";
620                 &copy_template_file($template);
621                 if ($template ne "harddisk") {
622                   unless ( -e "$amandahomedir/holdings/$config" ) {
623                     &create_holding;
624                   }
625                 } else {  # harddisk and template only
626                   unless ( -e "$amandahomedir/vtapes/$config" || defined $novtape ) {
627                     &create_vtape;
628                   }
629                 }
630               }
631         &copy_chg_manual_conf;
632       } else {
633 &create_customconf;
634 }
635
636 &check_xinetd;
637 &build_amanda_ssh_key;
638
639 if ( $vtape_err ) {
640   &mprint("Error in creating virtual tape, please check log and create virtual tape manually.\n");
641   exit 1;
642 }
643
644 if ( $holding_err ) {
645   &mprint("Error in creating holding disk, please check log and create holding disk manually.\n");
646   exit 1;
647 }
648
649
650
651 if ( $vtape_err==0 && $holding_err==0) {
652   &mprint("DONE.\n");
653   exit 0;
654 }
655
656
657 $ENV{'PATH'} = $oldPATH;
658
659
660 # THE END
661 Amanda::Util::finish_application();