Imported Upstream version 3.2.0
[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                 $tapedev=~/^(file:\/)/;
236                 $parentdir=$';
237                 }
238         }
239         else {
240                 $mylabelprefix=$config;
241                 &create_deftapedir;     
242         }
243         unless ( -e $parentdir){
244                 &mprint ("WARNING: tapedev $parentdir does not exists, vtapes creation failed!\n");
245                 &mprint ("Please create $parentdir and $confdir/$config and rerun the same command or else create vtapes manually.\n");
246                 $vtape_err++;
247                 return;
248         }
249
250         chdir ("$parentdir") ||
251                 ( &mprint("WARNING: chdir $parentdir failed: $!\n"), $vtape_err++, return );
252     my $i;
253     &mprint ("amlabel vtapes\n");
254         if (defined $tapecycle) {
255                 $tapecycle=~/^\d+/; 
256                 $tp_cyclelimit=$&;
257                         # check space
258                 my $dfout =`df $parentdir`;
259                 my $mul=1024;
260                 @dfdata=split(" ",$dfout);
261                 unless ( $dfdata[1] eq "1K-blocks" ) {
262                         $mul=512;       # 512-blocks displayed by df
263                 }
264                 if (($dfdata[10]*$mul) < (($tp_cyclelimit*73728)+10240)){
265                         &mprint ("WARNING: Not enough space for vtapes. 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         if ((!(defined($template)))||($template eq "harddisk")) 
313           {
314                 if (defined $tapedev){
315                 $tapedev="file:/".$tapedev;
316                 }
317                 unless ( $tpchanger ) { $tpchanger="chg-disk"; }
318                 unless ( $tapedev ) { $tapedev="$def_tapedev/$config"; }
319                 unless ( $changerfile ) { $changerfile="$confdir/$config/changer.conf"; }
320                 unless ( $changerdev ) { $changerdev="/dev/null";}
321                 unless ( $tapetype ) { $tapetype="HARDDISK"; }  
322           }
323         elsif ($template eq "single-tape")
324           {
325                 unless ($tpchanger) {$tpchanger="chg-manual";}
326                 unless ($tapedev)     {$tapedev="/dev/nst0";}
327                 unless ($changerfile) {$changerfile="$confdir/$config/chg-manual.conf";}
328                 unless ($changerdev) {$changerdev="/dev/null";}
329                 unless ($tapetype) {$tapetype="HP-DAT";}
330           }
331         elsif ($template eq "tape-changer") 
332           {
333                 unless ($tpchanger){$tpchanger="chg-zd-mtx";}
334                 unless ($tapedev){ $tapedev="/dev/nst0";}
335                 unless ($changerfile){$changerfile="$confdir/$config/changer.conf";}
336                 unless ($changerdev) {$changerdev="/dev/sg1";}
337                 unless ($tapetype)  {$tapetype="HP-DAT";}
338           }
339         else # S3 case
340           {
341             unless ($tpchanger){$tpchanger="chg-multi";}
342             unless ($changerfile){$changerfile="$confdir/$config/changer.conf";}
343             unless ($tapetype)  {$tapetype="HP-DAT";}
344           }
345
346
347         open (CONF, ">$confdir/$config/amanda.conf") ||
348             &log_and_die ("ERROR: Cannot create amanda.conf file: $!\n", 1);
349         chmod ($amanda_conf_perm, "$confdir/$config/amanda.conf") ||
350             &log_and_die ("ERROR: Cannot set amanda.conf file access permission: $!\n", 1);
351
352         print CONF "org \"$config\"\t\t# your organization name for reports\n";
353         print CONF "dumpuser \"$dumpuser\"\t# the user to run dumps under\n";
354         print CONF "mailto \"$mailto\"\t# space separated list of operators at your site\n";
355         print CONF "dumpcycle $dumpcycle\t\t# the number of days in the normal dump cycle\n";
356         print CONF "runspercycle $runspercycle\t\t# the number of amdump runs in dumpcycle days\n";
357         print CONF "tapecycle $tapecycle\t# the number of tapes in rotation\n"; 
358         print CONF "runtapes $runtapes\t\t# number of tapes to be used in a single run of amdump\n";
359         print CONF "tpchanger \"$tpchanger\"\t# the tape-changer glue script\n";
360         print CONF "tapedev \"$tapedev\"\t# the no-rewind tape device\n";
361         print CONF "changerfile \"$changerfile\"\t# tape changer configuration parameter file\n";
362         print CONF "changerdev \"$changerdev\"\t# tape changer configuration parameter device\n";
363         print CONF "tapetype $tapetype\t# what kind of tape it is\n";
364         print CONF "labelstr \"$labelstr\"\t# label constraint regex: all tapes must match\n";
365         print CONF "dtimeout $def_dtimeout\t# number of idle seconds before a dump is aborted\n";
366         print CONF "ctimeout $def_ctimeout\t# max number of secconds amcheck waits for each client\n";
367         print CONF "etimeout $def_etimeout\t# number of seconds per filesystem for estimates\n";
368         print CONF "define dumptype global {\n";
369         print CONF "       comment \"Global definitions\"\n";
370         print CONF "       auth \"bsdtcp\"\n}\n";
371         print CONF "define dumptype gui-base {\n";
372         print CONF "       global\n";
373         print CONF "       program \"GNUTAR\"\n";
374         print CONF "       comment \"gui base dumptype dumped with tar\"\n";
375         print CONF "       compress none\n";
376         print CONF "       index yes\n}\n";
377         if ($tapetype eq "HARDDISK") {
378           print CONF "define tapetype HARDDISK {\n";
379           print CONF "       comment \"Virtual Tapes\"\n";
380           print CONF "       length 5000 mbytes\n}\n";
381         }
382         print CONF "includefile \"advanced.conf\"\n";
383         print CONF "includefile \"$confdir/template.d/dumptypes\"\n";
384         print CONF "includefile \"$confdir/template.d/tapetypes\"\n";
385         close (CONF);
386         mprint ("custom amanda.conf created\n");
387   }
388
389
390 sub check_xinetd{
391     &mprint ("/var/lib/amanda/example/xinetd.amandaserver contains the latest Amanda server daemon configuration.\n");
392     &mprint ("Please merge it to /etc/xinetd.d/amandaserver.\n");
393 }
394
395
396 sub build_amanda_ssh_key{
397   if ( -e "$amandahomedir/.ssh/id_rsa_amdump.pub" ) {
398     if ( -e "$amandahomedir/.ssh/client_authorized_key" ) {
399       &mprint ("$amandahomedir/.ssh/client_authorized_keys exists.\n");
400     }
401     else {
402       open(NEWAUTH, ">$amandahomedir/.ssh/client_authorized_keys") ||
403         (&mprint("WARNING: open $amandahomedir/.ssh/client_authorized_key failed: $!\n"), return);
404       open(PUB, "$amandahomedir/.ssh/id_rsa_amdump.pub") ||
405         (&mprint("WARNING: open $amandahomedir/.ssh/id_rsa_amdump.pub failed: $!\n"), return);
406       print NEWAUTH "from=\"$host\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=\"/usr/lib/amanda/amandad -auth=ssh amdump\" ";
407       while (<PUB>) {
408       print NEWAUTH;
409     }
410       close NEWAUTH;
411       close PUB;
412       &mprint("$amandahomedir/.ssh/client_authorized_keys created. Please append to /var/lib/amanda/.ssh/authorized_keys file on Amanda clients\n");
413       }
414   }
415 }
416
417 sub copy_chg_manual_conf {
418   if ( $template eq "single-tape" && !defined $changerfile && !defined $tpchanger)
419     {
420       my $my_changerfile="$confdir/$config/chg-manual.conf";
421       copy("$templatedir/chg-manual.conf", $my_changerfile) ||
422         &mprint ("copy $templatedir/chg-manual.conf to $my_changerfile failed: $!\n");
423     }
424 }
425
426 #main
427 my $ret=0;
428
429 $ret = GetOptions ("template=s"=>\$template,
430                    "no-vtape!"=>\$novtape,
431               "tapetype=s"=>\$tapetype,
432               "tpchanger=s"=>\$tpchanger,
433               "tapedev=s"=>\$tapedev,
434               "changerfile=s"=>\$changerfile,
435               "changerdev=s"=>\$changerdev,
436               "labelstr=s"=>\$labelstr,
437               "mailto=s"=>\$mailto,
438               "dumpcycle=s"=>\$dumpcycle,
439               "runspercycle=i"=>\$runspercycle,
440               "runtapes=i"=>\$runtapes,
441               "tapecycle=i"=>\$tapecycle,
442               "help!"=>\$help
443               );
444
445 unless ( $ret ) {
446     &usage;
447     exit 1;
448 }
449
450 if($help) {
451     &usage;
452     exit 0;
453 }
454
455 unless ( $#ARGV == 0 ) {
456     print STDERR "ERROR: config name is required.\n";
457     &usage;
458     exit 1;
459 }
460 else {
461     if ( "$ARGV[0]" =~ /^([-\@\w.]+)$/ ) {
462         $config = $1;                   #  now untainted
463     } else {
464         die ("ERROR: Invalid data in config name.\n");  # log this somewhere
465     }
466 }
467
468
469 $oldPATH = $ENV{'PATH'};
470
471 $ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin:/usr/ucb"; # force known path
472 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
473 $date=`date +%Y%m%d%H%M%S`;
474 chomp($date);
475 my $logfile="$tmpdir/amserverconfig.$date.debug";
476
477 Amanda::Util::setup_application("amserverconfig", "server", $CONTEXT_CMDLINE);
478 Amanda::Util::finish_setup($RUNNING_AS_ANY);
479
480 unless ( -e "$tmpdir" ) {
481     mkpath ("$tmpdir", $def_perm) ||
482         die ("ERROR: mkpath: $tmpdir failed: $!\n");
483 }
484
485 open (LOG, ">$logfile") || die ("ERROR: Cannot create logfile: $!\n");
486 print STDOUT "Logging to $logfile\n";
487
488 my $lhost=`hostname`;
489 chomp($lhost);
490 # get our own canonical name, if possible (we don't sweat the IPv6 stuff here)
491 $host=(gethostbyname($lhost))[0];
492
493 unless ( $host ) {
494     $host = $lhost;  #gethostbyname() failed, go with hostname output
495 }
496
497
498 my $need_changer = 0;
499 if ( defined $template ) {
500
501     # validate user input to template
502     chomp($template);
503     my $found = 0;
504     @valid_templates = ( "harddisk", "single-tape", "tape-changer", "s3" );
505     foreach $elt (@valid_templates) {
506         if ( $elt eq lc($template) ) {
507             $found = 1;
508             last;
509         }
510     }
511     unless ($found) {
512         print STDERR
513             "valid inputs to --templates are harddisk, single-tape, tape-changer or S3\n";
514         &usage;
515         exit 1;
516     }
517
518     # if tape-changer is chosen, check if mtx is installed
519     if ( $template eq "tape-changer" ) {
520         my $ok = 0;
521         for $dir ( "/usr/sbin", "/usr/local/sbin", "/usr/local/bin",
522             "/usr/bin", "/bin", "/opt/csw/sbin", split( ":", $oldPATH ) )
523         {
524             if ( -e "$dir/mtx" ) {
525                 $ok = 1;
526                 last;
527             }
528         }
529         unless ($ok) {
530             &mprint(
531                 "ERROR: mtx binary not found, tape-changer template will not work and is not installed.\n"
532             );
533             &log_and_die(
534                 "ERROR: Please install mtx and rerun the same command.\n",
535                 0 );
536         }
537         $need_changer = 1;
538     }
539     elsif ( $template eq "S3" ) {
540         $need_changer = 1;
541     }
542
543 }
544
545 &create_conf_dir;
546
547 if ($need_changer) {
548     unless ($changerfile) {
549         $changerfile = "$confdir/$config/changer.conf";
550     }
551     open( CCONF, ">$changerfile" )
552         || &log_and_die( "ERROR: Cannot create $changerfile: $!\n", 1 );
553     close(CCONF);
554 }
555
556 &check_gnutarlist_dir;
557
558 # copy dumptypes and tapetypes files if none exists.
559 my $dtype="$confdir/template.d/dumptypes";
560 my $ttype="$confdir/template.d/tapetypes";
561
562 unless ( -e $dtype ) {
563     copy("$templatedir/dumptypes", $dtype ) ||
564     &log_and_die ("ERROR: copy dumptypes failed: $!\n", 1);
565 }
566
567
568 unless ( -e $ttype ) {
569     copy("$templatedir/tapetypes", $ttype ) ||
570     &log_and_die ("ERROR: copy tapetypes file to $ttype failed: $!\n", 1);
571 }
572
573
574
575 # update $def_config value to the specified config value in advanced.conf
576     open(ADV, "$templatedir/advanced.conf") || &log_and_die ("ERROR: Cannot open advanced.conf file: $!\n", 1);
577     open(NEWADV, ">$confdir/$config/advanced.conf") || 
578         &log_and_die ("ERROR: Cannot create advanced.conf file: $!\n", 1);
579     while (<ADV>) {
580         $_ =~ s/$def_config/$config/;
581         print NEWADV $_;
582     }
583     close(ADV);
584     close(NEWADV);
585     &mprint ("$confdir/$config/advanced.conf created and updated\n");
586
587
588 &create_curinfo_index_dir;
589 &touch_list_files;
590
591
592 if ( defined $template ) {
593 # if any other parameters are provided, create a workable custom config
594         if ( defined $tapetype || defined $tpchanger || defined $tapedev
595          || defined $changerdev || defined $labelstr || defined $mailto || defined $dumpcycle
596          || defined $runspercycle || defined $runtapes || defined $tapecycle ) {
597                 &mprint("Creating custom configuration using templates\n");
598                 create_customconf();
599                 if ( $template ne "harddisk" ) {
600                   &create_holding;
601                 } else {
602                   if (defined $labelstr) {
603                     if ($labelstr=~/^([-\w.]+)$/) {
604                       &create_vtape unless ( defined $novtape );
605                     } else {
606                       &mprint ("WARNING: Only alphanumeric string is supported in labelstr when using template to create vtapes. ");
607                       &mprint ("If you want to use regex in labelstr, please create vtapes manually.\n");
608                     }
609                   }
610                 }
611               } else {
612                 $template_only=1;
613                 $tapedev="$def_tapedev/$config";
614                 &copy_template_file($template);
615                 if ($template ne "harddisk") {
616                   unless ( -e "$amandahomedir/holdings/$config" ) {
617                     &create_holding;
618                   }
619                 } else {  # harddisk and template only
620                   unless ( -e "$amandahomedir/vtapes/$config" || defined $novtape ) {
621                     &create_vtape;
622                   }
623                 }
624               }
625         &copy_chg_manual_conf;
626       } else {
627 &create_customconf;
628 }
629
630 &check_xinetd;
631 &build_amanda_ssh_key;
632
633 if ( $vtape_err ) {
634   &mprint("Error in creating virtual tape, please check log and create virtual tape manually.\n");
635   exit 1;
636 }
637
638 if ( $holding_err ) {
639   &mprint("Error in creating holding disk, please check log and create holding disk manually.\n");
640   exit 1;
641 }
642
643
644
645 if ( $vtape_err==0 && $holding_err==0) {
646   &mprint("DONE.\n");
647   exit 0;
648 }
649
650
651 $ENV{'PATH'} = $oldPATH;
652
653
654 # THE END
655 Amanda::Util::finish_application();