Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tests / afs-newcell.pl
1 #!/usr/bin/env perl
2 # Copyright (C) 2000 by Sam Hartman
3 # This file may be copied either under the terms of the GNU GPL or the IBM Public License
4 # either version 2 or later of the GPL or version 1.0 or later of the IPL.
5
6 use warnings;
7 use strict;
8 use Term::ReadLine;
9 use OpenAFS::ConfigUtils;
10 use OpenAFS::Dirpath;
11 use OpenAFS::OS;
12 use OpenAFS::Auth;
13 use Getopt::Long;
14 use Pod::Usage;
15 use Socket;
16
17 =head1 NAME
18
19 afs-newcell - Set up the initial database and file server for a new OpenAFS cell.
20
21 =head1 SYNOPSIS
22
23 B<afs-newcell>
24 [ B<--batch> ]
25 [ B<--debug> ]
26 [ B<--unwind> ]
27 [ B<--help> ]
28 [ B<--server>=hostname ]
29 [ B<--cellname>=cell ]
30 [ B<--partition>=partition ]
31 [ B<--admin>=administrator ]
32 [ B<--kerberos-type>=authentication_type ]
33 [ B<--kerberos-realm>=realm_name ]
34 [ B<--kerberos-keytab>=keytab_file ]
35 [ B<--with-dafs> ]
36 [ B<--options-ptserver>=options ]
37 [ B<--options-vlserver>=options ]
38 [ B<--options-fileserver>=options ]
39 [ B<--options-volserver>=options ]
40 [ B<--options-salvageserver>=options ]
41 [ B<--options-salvager>=options ]
42
43 =head1 DESCRIPTION
44
45 This script sets up the initial AFS database and configures the first
46 database/file server. It also sets up an AFS cell's root volumes. The
47 fileserver and database server binaries must already be installed. The
48 fileserver should have an empty root.afs. This script creates root.cell, user,
49 service and populates root.afs.
50
51 The B<batch> option specifies that the initial requirements have been met and
52 that the script can proceed without displaying the initial banner or asking for
53 confirmation.
54
55 The B<admin> option specifies the name of the administrative user.
56 This user will be given system:administrators and susers permission in
57 the cell.
58
59 The B<cellname> option specifies the name of the cell.
60
61 The B<partition> option specifies the partition letter of the AFS partition. The
62 default value is 'a', for /vicepa.
63
64 =head1 PREREQUISITES
65
66 The following requirements must be met before running
67 this script.
68
69 This machine must have a working, empty filesystem mounted on /vicepa. A
70 different partition letter may be specified by the partition command line
71 option. For example, to use /vicepb, specify '--partition=b' on the command
72 line.
73
74 The OpenAFS client and server binaries must be installed on this machine.
75
76 A working Kerberos realm with Kerberos4 support must be available. Supported
77 Kerberos implementations are Heimdal with Kth-kerberos compatibility, MIT
78 Kerberos5, and Kaserver (deprecated).
79
80 Create the single-DES AFS key and write it to a keytab file using the kerberos
81 kadmin program.
82
83 Create a principal called afs/cellname in your realm. The cell name should be
84 all lower case, unlike Kerberos realms which are all upper case. You can use
85 the asetkey command or if you used AFS3 salt to create the key, the bos addkey
86 command. The asetkey command is built when OpenAFS built with Kerberos support.
87 The asetkey command requires a cell configuration.
88
89 You will need an administrative principal created in a Kerberos realm. This
90 principal will be added to system:administrators and thus will be able to run
91 administrative commands. Generally the user is a root instance of some
92 administrative user. For example if jruser is an administrator then it would be
93 reasonable to create jruser/root and specify jruser/root as the user to be
94 added in this script using the 'admin' command line option. You will also need
95 to create a keyfile for this adminstrative user which is used by the script to
96 obtain a ticket. The keyfile must be located in
97 $openafsdirpath->{'afsconfdir'}/krb5.conf.
98
99 The AFS client must not be running on this workstation. It will be started
100 during the execution of this script.
101
102 =head1 AUTHOR
103
104 Sam Hartman <hartmans@debian.org>
105
106 =cut
107
108
109 my $term = new Term::ReadLine('afs-newcell');
110 my $path = $OpenAFS::Dirpath::openafsdirpath;
111
112 #-----------------------------------------------------------------------------------
113 # prompt(message, default_value)
114 #
115 sub prompt($$) {
116 my ($message,$default) = @_;
117 my $value = $term->readline("$message [$default] ");
118 unless ($value) {
119 $value = $default;
120 }
121 return $value;
122 }
123
124 #-----------------------------------------------------------------------------------
125 # mkvol(volume, mount, partition)
126 #
127 sub mkvol($$$$) {
128 my ($vol, $mnt, $srv, $part) = @_;
129 run("$path->{'afssrvsbindir'}/vos create $srv $part $vol -maxquota 0");
130 unwind("$path->{'afssrvsbindir'}/vos remove $srv $part $vol");
131 run("$path->{'afssrvbindir'}/fs mkmount $mnt $vol ");
132 run("$path->{'afssrvbindir'}/fs setacl $mnt system:anyuser rl");
133 }
134
135 #-----------------------------------------------------------------------------------
136 # check_program($prog) - verify the program is installed.
137 #
138 sub check_program($) {
139 my ($program) = @_;
140 unless ( -f $program ) {
141 die "error: Missing program: $program\n";
142 }
143 unless ( -x $program ) {
144 die "error: Not executable: $program\n";
145 }
146 }
147
148 #-----------------------------------------------------------------------------------
149 # main script
150
151 # options
152 my $batch = 0;
153 my $debug = 0;
154 my $unwind = 1;
155 my $help = 0;
156 my $cellname = 'testcell';
157 my $partition = 'a';
158 my $admin = 'admin';
159 my $kerberos_type = 'MIT';
160 my $kerberos_realm = 'TESTCELL';
161 my $kerberos_keytab = "$path->{'afsconfdir'}/krb5.keytab";
162 my $with_dafs = 0;
163 my $options_ptserver = '';
164 my $options_vlserver = '';
165 my $options_fileserver = '';
166 my $options_volserver = '';
167 my $options_salvageserver = '';
168 my $options_salvager = '';
169
170 my $server = `hostname -f`;
171 chomp $server;
172
173 GetOptions (
174 "batch!" => \$batch,
175 "debug!" => \$debug,
176 "unwind!" => \$unwind,
177 "help" => \$help,
178 "server=s" => \$server,
179 "cellname=s" => \$cellname,
180 "partition=s" => \$partition,
181 "admin=s" => \$admin,
182 "kerberos-type=s" => \$kerberos_type,
183 "kerberos-realm=s" => \$kerberos_realm,
184 "kerberos-keytab=s" => \$kerberos_keytab,
185 "with-dafs" => \$with_dafs,
186 "options-ptserver=s" => \$options_ptserver,
187 "options-vlserver=s" => \$options_vlserver,
188 "options-fileserver=s" => \$options_fileserver,
189 "options-volserver=s" => \$options_volserver,
190 "options-salvageserver=s" => \$options_salvageserver,
191 "options-salvager=s" => \$options_salvager,
192 );
193
194 if ($help) {
195 pod2usage(1);
196 exit 0;
197 }
198
199 # To print debug messages in the run() calls.
200 $OpenAFS::ConfigUtils::debug = $debug;
201
202 #-----------------------------------------------------------------------------
203 # Prereq: Must be root and must not already have a cell configuration.
204 #
205 my @problems = ();
206 my $try_rm_cell = 0;
207
208 if ($> != 0) {
209 push(@problems, "You must be root to run this script.");
210 }
211
212 my @afsconfigfiles = (
213 "$path->{'afsconfdir'}/ThisCell",
214 "$path->{'afsconfdir'}/CellServDB",
215 "$path->{'afsconfdir'}/UserList",
216 "$path->{'afsdbdir'}/prdb.DB0",
217 "$path->{'afsbosconfigdir'}/BosConfig",
218 "$path->{'afsddir'}/ThisCell",
219 "$path->{'afsddir'}/CellServDB",
220 );
221 foreach my $configfile (@afsconfigfiles) {
222 if ( -f $configfile ) {
223 push(@problems, "Configuration file already exists, $configfile.");
224 $try_rm_cell = 1;
225 }
226 }
227
228 if (@problems) {
229 foreach my $problem (@problems) {
230 print "error: $problem\n";
231 }
232 print "info: Try running afs-rmcell.pl\n" if $try_rm_cell;
233 exit 1;
234 }
235
236 #-----------------------------------------------------------------------------
237 # Prereq: System requirements notification.
238 #
239 unless ($batch) {
240
241 print <<eoreqs;
242 REQUIREMENTS
243
244 The following requirements must be meet before running
245 this script. See 'pod2text $0' for more details.
246
247 1) A filesystem must be mounted on /vicepa. (See
248 the --partition option for alternative mount points.)
249
250 2) The OpenAFS client and server binaries must be installed.
251 There should be no remnants from a previous cell.
252 Run afs-rmcell to remove any.
253
254 3) A Kerberos realm with Kerberos 4 support must be available.
255 Supported Kerberos implementations are Heimdal with
256 Kth-kerberos compatibility, MIT Kerberos 5, and
257 Kaserver (deprecated).
258
259 4) A Kerberos keytab file containing the afs principal
260 and the administrator principal must be be present.
261 See the asetkey man page for information about creating the
262 keytab file. The default name of the administrator
263 principal is 'admin'. See the --admin option for
264 alternative names.
265
266 eoreqs
267
268 my $answer = prompt("Does your system meet these requirements? (yes/no)", "no");
269 unless ($answer=~/^y/i ) {
270 print "OK: Aborted.\n";
271 exit 0;
272 }
273 }
274
275 #-----------------------------------------------------------------------------
276 # Prereq: Verify required binaries, directories, and permissions.
277 #
278 my $bosserver = "$path->{'afssrvsbindir'}/bosserver";
279 my $bos = "$path->{'afssrvbindir'}/bos";
280 my $fs = "$path->{'afssrvbindir'}/fs";
281 my $pts = "$path->{'afssrvbindir'}/pts";
282 my $vos = "$path->{'afssrvsbindir'}/vos";
283 my $afsrc = "$path->{'initdir'}/afs.rc";
284 my $aklog = "$path->{'afswsbindir'}/aklog";
285 my $tokens = "$path->{'afswsbindir'}/tokens";
286 my $klog = "$path->{'afswsbindir'}/klog";
287 my $kas = "$path->{'afssrvsbindir'}/kas";
288
289 check_program($bosserver);
290 check_program($bos);
291 check_program($fs);
292 check_program($pts);
293 check_program($vos);
294 check_program($afsrc);
295 check_program($tokens);
296
297 #-----------------------------------------------------------------------------
298 # Prereq: Cell configuration
299 #
300 if ($batch) {
301 if ($kerberos_type!~/kaserver/i) {
302 check_program($aklog);
303 unless ( -f $kerberos_keytab ) {
304 die "error: Missing keytab file: $kerberos_keytab\n";
305 }
306 }
307 }
308 else {
309 my $answer;
310 get_options: {
311 $answer = prompt("Print afs-newcell debugging messages? (yes/no)", $debug ? "yes" : "no");
312 $debug = ($answer=~/^y/i) ? 1 : 0;
313
314 print "\nServer options:\n";
315 $server = prompt("What server name should be used?", $server);
316 $cellname = prompt("What cellname should be used?", $cellname);
317 $partition = prompt("What vice partition?", $partition);
318 $admin = prompt("What administrator username?", $admin);
319 if($admin =~ /@/) {
320 die "error: Please specify the username without the realm name.\n";
321 }
322
323 print "\nKerberos options:\n";
324 $kerberos_type = prompt("Which Kerberos is to be used?", $kerberos_type);
325 if ($kerberos_type=~/kaserver/i) {
326 check_program($klog);
327 check_program($kas);
328 }
329 else {
330 check_program($aklog);
331 $kerberos_realm = $cellname;
332 $kerberos_realm =~ tr/a-z/A-Z/;
333 $kerberos_realm = prompt("What Kerberos realm?", $kerberos_realm);
334 get_keytab: {
335 $kerberos_keytab = prompt("What keytab file?", $kerberos_keytab);
336 unless ( -f $kerberos_keytab ) {
337 print "Cannot find keytab file $kerberos_keytab\n";
338 redo get_keytab;
339 }
340 }
341 }
342
343 print "\nDatabase Server options:\n";
344 $options_ptserver = prompt("ptserver options:", $options_ptserver);
345 $options_vlserver = prompt("vlserver options:", $options_vlserver);
346
347 print "\nFileserver options:\n";
348 $answer = prompt("Use DAFS fileserver (requires DAFS build option)? (yes/no)", "no");
349 $with_dafs = ($answer=~/^y/i) ? 1 : 0;
350 $options_fileserver = prompt("fileserver options:", $options_fileserver);
351 $options_volserver = prompt("volserver options:", $options_volserver);
352 $options_salvageserver = prompt("salvageserver options:", $options_salvageserver);
353 $options_salvager = prompt("salvager options:", $options_salvager);
354
355 print "\nConfirmation:\n";
356 print "Server name : $server\n";
357 print "Cell name : $cellname\n";
358 print "Partition : $partition\n";
359 print "Administrator : $admin\n";
360 print "Kerberos : $kerberos_type\n";
361 if ($kerberos_type!~/kaserver/i) {
362 print "Realm : $kerberos_realm\n";
363 print "Keytab file : $kerberos_keytab\n";
364 }
365 print "DAFS fileserver : ", $with_dafs ? "yes" : "no", "\n";
366 print "ptserver options : $options_ptserver\n";
367 print "vlserver options : $options_vlserver\n";
368 print "fileserver options : $options_fileserver\n";
369 print "volserver options : $options_volserver\n";
370 print "salvagerserver options : $options_salvageserver\n";
371 print "salvager options : $options_salvager\n";
372 print "\n";
373
374 $answer = prompt("Correct? (yes/no/quit)", "yes");
375 exit(0) if $answer=~/^q/i;
376 redo get_options if $answer!~/^y/i;
377 }
378
379 # Save the options as a shell script for the next run.
380 $answer = prompt("Save these options? (yes/no)", "yes");
381 if ($answer=~/^y/i ) {
382 my $script = '';
383 get_script_name: {
384 $script = prompt("File name for save?", "run-afs-newcell.sh");
385 last get_script_name if ! -f $script;
386
387 $answer = prompt("File $script already exists. Overwrite? (yes/no/quit)", "no");
388 exit(0) if $answer=~/^q/i;
389 last get_script_name if $answer=~/^yes/i;
390 redo get_script_name;
391 }
392
393 my @switches = ();
394 push(@switches, "--batch"); # automatically added to the script
395 push(@switches, "--debug") if $debug;
396 push(@switches, "--nounwind") unless $unwind;
397 push(@switches, "--server='$server'") if $server;
398 push(@switches, "--cellname='$cellname'") if $cellname;
399 push(@switches, "--partition='$partition'") if $partition;
400 push(@switches, "--admin='$admin'") if $admin;
401 push(@switches, "--kerberos-type='$kerberos_type'") if $kerberos_type;
402 push(@switches, "--kerberos-realm='$kerberos_realm'") if $kerberos_realm;
403 push(@switches, "--kerberos-keytab='$kerberos_keytab'") if $kerberos_keytab;
404 push(@switches, "--with-dafs") if $with_dafs;
405 push(@switches, "--options-ptserver='$options_ptserver'") if $options_ptserver;
406 push(@switches, "--options-vlserver='$options_vlserver'") if $options_vlserver;
407 push(@switches, "--options-fileserver='$options_fileserver'") if $options_fileserver;
408 push(@switches, "--options-volserver='$options_volserver'") if $options_volserver;;
409 push(@switches, "--options-salvageserver='$options_salvageserver'") if $options_salvageserver;;
410 push(@switches, "--options-salvager='$options_salvager'") if $options_salvager;
411
412 open(SCRIPT, "> $script") or die "error: Cannot open file $script: $!\n";
413 print SCRIPT "#!/bin/sh\n";
414 print SCRIPT "perl afs-newcell.pl \\\n";
415 print SCRIPT join(" \\\n", map(" $_", @switches));
416 print SCRIPT "\n\n";
417 close SCRIPT;
418 chmod(0755, $script);
419 }
420 }
421
422 if ($debug) {
423 print "debug: afs-newcell options\n";
424 print "debug: \$batch = '$batch'\n";
425 print "debug: \$debug = '$debug'\n";
426 print "debug: \$unwind = '$unwind'\n";
427 print "debug: \$help = '$help'\n";
428 print "debug: \$server = '$server'\n";
429 print "debug: \$cellname = '$cellname'\n";
430 print "debug: \$partition = '$partition'\n";
431 print "debug: \$admin = '$admin'\n";
432 print "debug: \$kerberos_type = '$kerberos_type'\n";
433 print "debug: \$kerberos_realm = '$kerberos_realm'\n";
434 print "debug: \$kerberos_keytab = '$kerberos_keytab'\n";
435 print "debug: \$with_dafs = '$with_dafs'\n";
436 print "debug: \$options_pteserver = '$options_ptserver'\n";
437 print "debug: \$options_pteserver = '$options_vlserver'\n";
438 print "debug: \$options_fileserver = '$options_fileserver'\n";
439 print "debug: \$options_volserver = '$options_volserver'\n";
440 print "debug: \$options_salvageserver = '$options_salvageserver'\n";
441 print "debug: \$options_salvager = '$options_salvager'\n";
442 }
443
444
445 #-----------------------------------------------------------------------------
446 # Prereq: Sanity check the forward and reverse name resolution.
447 #
448 if ($server eq 'localhost') {
449 die "error: localhost is not a valid --server parameter. Use the ip hostname of this machine.\n";
450 }
451 my $packed_ip = gethostbyname($server);
452 unless (defined $packed_ip) {
453 die "error: gethostbyname failed, $?\n";
454 }
455 my $ip_from_name = inet_ntoa($packed_ip);
456 print "debug: $server ip address is $ip_from_name\n" if $debug;
457 if ($ip_from_name=~/^127/) {
458 die "error: Loopback address $ip_from_name cannot not be used for server $server. Check your /etc/hosts file.\n";
459 }
460
461 my $name_from_ip = gethostbyaddr($packed_ip, AF_INET);
462 print "debug: hostname of $ip_from_name is $name_from_ip\n" if $debug;
463 if ($name_from_ip ne $server) {
464 die "error: Name from ip $name_from_ip does not match ip from name $ip_from_name for --server $server. ".
465 " Use the correct --server parameter and verify forward and reverse name resolution is working.\n";
466 }
467
468 #-----------------------------------------------------------------------------
469 # Prereq: The vice partition must be available and empty.
470 #
471 unless ($partition=~/^(([a-z])|([a-h][a-z])|([i][a-v]))$/) {
472 die "error: Invalid partition id specified: $partition. Valid values are a..z and aa..iv\n";
473 }
474 unless ( -d "/vicep$partition" ) {
475 die "error: Missing fileserver partition, /vicep$partition\n";
476 }
477 if ( -d "/vicep$partition/AFSIDat" ) {
478 die "error: Fileserver partition is not empty. /vicep$partition/AFSIDat needs to be removed.\n";
479 }
480 open(LS, "ls /vicep$partition |") or
481 die "error: ls /vicep$partition failed, $!\n";
482 while (<LS>) {
483 chomp;
484 if (/^V\d+.vol$/) {
485 die "error: Fileserver partition, /vicep$partition, is not empty.\n";
486 }
487 }
488 close LS;
489
490 # Prereq: authorization and platform specific objects.
491 my $auth = OpenAFS::Auth::create(
492 'debug'=>$debug,
493 'type'=>$kerberos_type,
494 'cell'=>$cellname,
495 'realm'=>$kerberos_realm,
496 'keytab'=>$kerberos_keytab,
497 'admin'=>$admin,
498 );
499
500 my $os = OpenAFS::OS::create(
501 'debug'=>$debug,
502 );
503
504 #-----------------------------------------------------------------------------
505 # Prereq: Sanity check admin username and convert kerberos 5 notation to afs.
506 #
507 if ($admin =~ /@/) {
508 die "error: Please specify the username without the realm name.\n";
509 }
510 my $username = $admin;
511 $username=~s:/:.:g; # convert kerberos separators to afs separators.
512
513 #-----------------------------------------------------------------------------
514 # Prereq: Save the setup configuration in a form that is easily
515 # read by the shell scripts.
516 #
517 open(CONF, "> run-tests.conf") or die "error: Cannot open file run-tests.conf for writing: $!\n";
518 print CONF <<"__CONF__";
519 CELLNAME=$cellname
520 PARTITION=$partition
521 ADMIN=$admin
522 KERBEROS_TYPE=$kerberos_type
523 KERBEROS_REALM=$kerberos_realm
524 KERBEROS_KEYTAB=$kerberos_keytab
525 __CONF__
526 close CONF;
527
528 unless ($batch) {
529 my $answer = prompt("Last chance to cancel before setup begins. Continue? (yes/no)", "yes");
530 exit(0) unless $answer=~/^y/i;
531 }
532
533 #-----------------------------------------------------------------------------
534 # Prereq: Shutdown the client and server, if running.
535 #
536 run($os->command('client-stop'));
537 run($os->command('fileserver-stop'));
538
539 #-----------------------------------------------------------------------------
540 # Prereq: Verify the server processes are not running.
541 #
542 foreach my $program ('bosserver', 'ptserver', 'vlserver', 'kaserver', 'fileserver') {
543 die "error: program is already running, $program\n" if $os->number_running($program);
544 }
545
546 #-----------------------------------------------------------------------------
547 # Perform Platform-Specific Procedures
548 $os->configure_client();
549
550 #-----------------------------------------------------------------------------
551 # WORKAROUND:
552 # bosserver attempts to create the following directories with these limited
553 # permissions. However, bosserver does not create parent directories as needed, so
554 # the directories are not successfully created when they are more than one level
555 # deep.
556 run("mkdir -m 0775 -p $path->{'afsconfdir'}");
557 run("mkdir -m 0700 -p $path->{'afslocaldir'}");
558 run("mkdir -m 0700 -p $path->{'afsdbdir'}");
559 run("mkdir -m 0755 -p $path->{'afslogsdir'}");
560 run("mkdir -m 0777 -p $path->{'viceetcdir'}");
561
562 # In case the directories were created earlier with the wrong permissions.
563 run("chmod 0775 $path->{'afsconfdir'}");
564 run("chmod 0700 $path->{'afslocaldir'}");
565 run("chmod 0700 $path->{'afsdbdir'}");
566 run("chmod 0755 $path->{'afslogsdir'}");
567 run("chmod 0777 $path->{'viceetcdir'}");
568
569 #-----------------------------------------------------------------------------
570 # Starting the BOS Server
571 #
572 # Start the bosserver and create the initial server configuration.
573 # Authorization is disabled by the -noauth flag.
574 #
575 print "debug: Starting bosserver...\n" if $debug;
576 run("$path->{'afssrvsbindir'}/bosserver -noauth");
577 if ($unwind) {
578 unwind($os->command('remove', "$path->{'afsconfdir'}/ThisCell"));
579 unwind($os->command('remove', "$path->{'afsconfdir'}/CellServDB"));
580 unwind($os->command('remove', "$path->{'afsconfdir'}/UserList"));
581 unwind($os->command('remove', "$path->{'afsconfdir'}/KeyFile"));
582 unwind($os->command('remove', "$path->{'afsbosconfigdir'}/BosConfig"));
583 unwind($os->command('fileserver-stop'));
584 }
585 sleep(10); # allow bosserver some time to start accepting connections...
586
587 #-----------------------------------------------------------------------------
588 # Defining Cell Name and Membership for Server Processes
589 #
590 run("$bos setcellname $server $cellname -noauth");
591 run("$bos addhost $server $server -noauth");
592 run("$bos adduser $server $username -noauth");
593 if ($unwind) {
594 unwind("$bos removeuser $server $username -noauth");
595 }
596
597 # WORKAROUND:
598 # The initial bosserver startup may create CellServDB entry which does
599 # not match the host name retured by gethostbyaddr(). This entry will
600 # cause ptserver/vlserver quorum errors and so is removed.
601 open(HOSTS, "$bos listhosts $server |") or
602 die "error: failed to run bos listhosts, $?\n";
603 my @hosts = <HOSTS>;
604 close HOSTS;
605 foreach (@hosts) {
606 chomp;
607 if (/^\s+Host \d+ is (.*)/) {
608 my $host = $1;
609 print "debug: bos listhosts: host=[$host]\n" if $debug;
610 if ($host ne $name_from_ip) {
611 print "debug: removing invalid host '$host' from CellServDB.\n" if $debug;
612 run("$bos removehost $server $host -noauth");
613 }
614 }
615 }
616
617 #-----------------------------------------------------------------------------
618 # Starting the Database Server Processes
619 #
620 print "debug: Starting the ptserver and vlserver...\n" if $debug;
621 run("$bos create $server ptserver simple -cmd \"$path->{'afssrvlibexecdir'}/ptserver $options_ptserver\" -noauth");
622 if ($unwind) {
623 unwind($os->command('remove', "$path->{'afsdbdir'}/prdb.DB0"));
624 unwind($os->command('remove', "$path->{'afsdbdir'}/prdb.DBSYS1"));
625 unwind("$bos delete $server ptserver -noauth");
626 unwind("$bos stop $server ptserver -noauth");
627 }
628
629 run("$bos create $server vlserver simple -cmd \"$path->{'afssrvlibexecdir'}/vlserver $options_vlserver\" -noauth");
630 if ($unwind) {
631 unwind($os->command('remove', "$path->{'afsdbdir'}/vldb.DB0"));
632 unwind($os->command('remove', "$path->{'afsdbdir'}/vldb.DBSYS1"));
633 unwind("$bos delete $server vlserver -noauth");
634 unwind("$bos stop $server vlserver -noauth");
635 }
636
637 if ($kerberos_type =~ /kaserver/i) {
638 print "warning: kaserver is deprecated!\n";
639 run("$bos create $server kaserver simple -cmd \"$path->{'afssrvlibexecdir'}/kaserver $options_vlserver\" -noauth");
640 if ($unwind) {
641 unwind($os->command('remove', "$path->{'afsdbdir'}/kaserver.DB0"));
642 unwind($os->command('remove', "$path->{'afsdbdir'}/kaserver.DBSYS1"));
643 unwind("$bos delete $server kaserver -noauth");
644 unwind("$bos stop $server kaserver -noauth");
645 }
646 }
647
648 sleep(10); # to allow the database servers to start servicing requests.
649
650 #-----------------------------------------------------------------------------
651 # Initializing Cell Security
652 #
653 # Create the AFS administrative account and the AFS server encryption key.
654 # Make the krb.conf file if the realm name is different than the cell name.
655
656 $auth->make_krb_config();
657 $auth->make_keyfile();
658 unless ( -f "$path->{'afsconfdir'}/KeyFile") {
659 die "Failed to create $path->{'afsconfdir'}/KeyFile. Please create this using asetkey or the bos addkey command.\n";
660 }
661
662 print "debug: Creating admin user...\n" if $debug;
663 run("$pts createuser -name $username -cell $cellname -noauth");
664 run("$pts adduser $username system:administrators -cell $cellname -noauth");
665 run("$pts membership $username -cell $cellname -noauth");
666
667 print "debug: Restarting the database servers to use the new encryption key.\n" if $debug;
668 run("$bos restart $server -all -noauth");
669 sleep(10); # to allow the database servers to start servicing requests.
670
671 #-----------------------------------------------------------------------------
672 # Starting the File Server, Volume Server, and Salvager
673 #
674 print "debug: Starting the fileserver...\n" if $debug;
675 if ($with_dafs) {
676 run( "$bos create $server dafs dafs ".
677 "-cmd \"$path->{'afssrvlibexecdir'}/fileserver $options_fileserver\" ".
678 "-cmd \"$path->{'afssrvlibexecdir'}/volserver $options_volserver\" ".
679 "-cmd \"$path->{'afssrvlibexecdir'}/salvageserver $options_salvageserver\" ".
680 "-cmd \"$path->{'afssrvlibexecdir'}/salvager $options_salvager\" ".
681 "-noauth");
682 if ($unwind) {
683 unwind("$bos delete $server dafs -noauth");
684 unwind("$bos stop $server dafs -noauth");
685 }
686 }
687 else {
688 run( "$bos create $server fs fs ".
689 "-cmd \"$path->{'afssrvlibexecdir'}/fileserver $options_fileserver\" ".
690 "-cmd \"$path->{'afssrvlibexecdir'}/volserver $options_volserver\" ".
691 "-cmd \"$path->{'afssrvlibexecdir'}/salvager $options_salvager\" ".
692 "-noauth");
693 if ($unwind) {
694 unwind("$bos delete $server fs -noauth");
695 unwind("$bos stop $server fs -noauth");
696 }
697 }
698
699 # Create the root.afs volume.
700 print "debug: Creating root.afs volume...\n" if $debug;
701 run("$vos create $server $partition root.afs -cell $cellname -noauth");
702 if ($unwind) {
703 unwind($os->command('remove', "$partition/AFSIDat "));
704 unwind($os->command('remove', "$partition/V*.vol"));
705 unwind($os->command('remove', "$partition/Lock"));
706 unwind("$vos remove $server $partition root.afs -cell $cellname -localauth");
707 }
708
709 #-----------------------------------------------------------------------------
710 # Installing Client Functionality
711 #
712 print "debug: Starting the OpenAFS client...\n" if $debug;
713 run($os->command('client-start'));
714 if ($unwind) {
715 unwind($os->command('client-stop'));
716 }
717
718 # Run as the administrator.
719 $auth->authorize();
720
721 #-----------------------------------------------------------------------------
722 # Configuring the Top Levels of the AFS Filespace
723 #
724 print "debug: Creating the volumes...\n" if $debug;
725 run("$fs setacl /afs system:anyuser rl");
726
727 run("$vos create $server $partition root.cell");
728 if ($unwind) {
729 unwind("$vos remove $server $partition root.cell -localauth");
730 }
731
732 run("$fs mkmount /afs/$cellname root.cell -cell $cellname -fast");
733 if ($unwind) {
734 unwind("$fs rmmount /afs/$cellname");
735 }
736
737 run("$fs setacl /afs/$cellname system:anyuser rl");
738 run("$fs mkmount /afs/.$cellname root.cell -cell $cellname -rw");
739 if ($unwind) {
740 unwind("$fs rmmount /afs/.$cellname");
741 }
742
743 run("$fs examine /afs");
744 run("$fs examine /afs/$cellname");
745
746 run("$vos addsite $server $partition root.afs");
747 run("$vos addsite $server $partition root.cell");
748 run("$vos release root.cell");
749 run("$vos release root.afs");
750
751 run("$fs checkvolumes"); # so client notices the releases
752 print "debug: the following should show root.afs.readonly\n" if $debug;
753 run("$fs examine /afs");
754 print "debug: the following should show root.cell.readonly\n" if $debug;
755 run("$fs examine /afs/$cellname");
756 print "debug: the following should show root.cell\n" if $debug;
757 run("$fs examine /afs/.$cellname");
758
759 # Create some volumes in our new cell.
760 print "debug: Creating the test volumes...\n" if $debug;
761 mkvol("user", "/afs/.$cellname/user", $server, $partition);
762 mkvol("service", "/afs/.$cellname/service", $server, $partition);
763 mkvol("unrep", "/afs/.$cellname/unreplicated", $server, $partition);
764 mkvol("rep", "/afs/.$cellname/replicated", $server, $partition);
765
766 run("$vos addsite $server $partition rep");
767 if ($unwind) {
768 unwind("$vos remsite $server $partition rep");
769 }
770 run("$vos release rep");
771 run("$fs mkmount /afs/.$cellname/.replicated rep -rw");
772 run("$fs setacl /afs/.$cellname/.replicated system:anyuser rl");
773
774 # Show the new volumes in the read-only path.
775 run("$vos release root.cell");
776
777 # done.
778 @unwinds = (); # clear unwinds
779 print "info: DONE\n";
780
781 END {
782 if ($unwind && scalar @unwinds) {
783 print "\ninfo: Error encountered, unwinding...\n";
784 while (@unwinds) {
785 eval {
786 run(pop(@unwinds));
787 };
788 if ($@) {
789 print "warn: Unwind command failed.\n$@\n";
790 }
791 }
792 }
793 }