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