Import Debian changes 1.8.5-1
[hcoop/debian/openafs.git] / debian / afs-newcell
diff --git a/debian/afs-newcell b/debian/afs-newcell
new file mode 100755 (executable)
index 0000000..87e0586
--- /dev/null
@@ -0,0 +1,289 @@
+#!/usr/bin/perl -w
+# Copyright (C) 2000 by Sam Hartman
+# This file may be copied either under the terms of the GNU GPL or the IBM
+# Public License either version 2 or later of the GPL or version 1.0 or later
+# of the IPL.
+
+use Term::ReadLine;
+use strict;
+use Debian::OpenAFS::ConfigUtils;
+use Getopt::Long;
+use Socket qw(inet_ntoa);
+use vars qw($admin $server $requirements_met $shutdown_needed);
+my $rl = new Term::ReadLine('afs-newcell');
+
+# The default file server options are poor.  Until they've been updated, use
+# the following from Harald Barth; it should be an improvement for most
+# people.
+my $fs_options = '-p 23 -busyat 600 -rxpck 400 -s 1200 -l 1200 -cb 65535'
+    . ' -b 240 -vc 1200';
+
+=head1  NAME
+
+afs-newcell - Set up initial database server for AFS cell
+
+=head1 SYNOPSIS
+
+B<afs-newcell> [B<--requirements-met>] [B<--admin> admin_user]
+
+=head1 DESCRIPTION
+
+This script sets up the initial AFS database and configures the first
+database/file server.
+
+The B<--requirements-met> option specifies that the initial requirements have
+been met and that the script can proceed without displaying the initial
+banner or asking for confirmation.
+
+The B<--admin> option specifies the name of the administrative user.  This
+user will be given system:administrators and susers permission in the cell.
+
+=head1 AUTHOR
+
+Sam Hartman <hartmans@debian.org>
+
+=cut
+
+# Flush all output immediately.
+$| = 1;
+
+GetOptions ("requirements-met" => \$requirements_met, "admin=s" => \$admin);
+
+unless ($requirements_met) {
+    print <<eoreqs;
+                            Prerequisites
+
+In order to set up a new AFS cell, you must meet the following:
+
+1) You need a working Kerberos realm with Kerberos4 support.  You
+   should install Heimdal with KTH Kerberos compatibility or MIT
+   Kerberos 5.
+
+2) You need to create the single-DES AFS key and load it into
+   /etc/openafs/server/KeyFile.  If your cell's name is the same as
+   your Kerberos realm then create a principal called afs.  Otherwise,
+   create a principal called afs/cellname in your realm.  The cell
+   name should be all lower case, unlike Kerberos realms which are all
+   upper case.  You can use asetkey from the openafs-krb5 package, or
+   if you used AFS3 salt to create the key, the bos addkey command.
+
+3) This machine should have a filesystem mounted on /vicepa.  If you
+   do not have a free partition, then create a large file by using dd
+   to extract bytes from /dev/zero.  Create a filesystem on this file
+   and mount it using -oloop.
+
+4) You will need an administrative principal created in a Kerberos
+   realm.  This principal will be added to susers and
+   system:administrators and thus will be able to run administrative
+   commands.  Generally the user is a root or admin instance of some
+   administrative user.  For example if jruser is an administrator then
+   it would be reasonable to create jruser/admin (or jruser/root) and
+   specify that as the user to be added in this script.
+
+5) The AFS client must not be running on this workstation.  It will be
+   at the end of this script.
+
+eoreqs
+#'# cperl-mode
+
+    $_ = $rl->readline("Do you meet these requirements? [y/n] ");
+    unless (/^y/i ) {
+        print "Run this script again when you meet the requirements\n";
+        exit(1);
+    }
+
+    if ($> != 0) {
+        die "This script should almost always be run as root.  Use the\n"
+            . "--requirements-met option to run as non-root.\n";
+    }
+}
+
+# Make sure the AFS client is not already running.
+open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
+while(<MOUNT>) {
+    if (m:^AFS:) {
+        print "The AFS client is currently running on this workstation.\n";
+        print "Please restart this script after running"
+            . " service openafs-client stop\n";
+        exit(1);
+    }
+}
+close MOUNT;
+
+# Make sure there is a keyfile.
+unless ( -f "/etc/openafs/server/KeyFile") {
+    print "You do not have an AFS keyfile.  Please create this using\n";
+    print "asetkey from openafs-krb5 or the bos addkey command\n";
+    exit(1);
+}
+
+# Stop the file server.
+print "If the fileserver is not running, this may hang for 30 seconds.\n";
+run("service openafs-fileserver stop");
+
+# Get the local hostname.  Use the fully-qualified hostname to be safer.
+$server = `hostname -f`;
+chomp $server;
+my $ip = gethostbyname $server;
+if (inet_ntoa($ip) eq '127.0.0.1') {
+    print "\n";
+    print "Your hostname $server resolves to 127.0.0.1, which AFS cannot\n";
+    print "cope with.  Make sure your hostname resolves to a non-loopback\n";
+    print "IP address.  (Check /etc/hosts and make sure that your hostname\n";
+    print "isn't listed on the 127.0.0.1 line.  If it is, removing it from\n";
+    print "that line will probably solve this problem.)\n";
+    exit(1);
+}
+
+# Determine the admin principal.
+$admin = $rl->readline("What administrative principal should be used? ")
+    unless $admin;
+print "\n";
+die "Please specify an administrative user\n" unless $admin;
+my $afs_admin = $admin;
+$afs_admin =~ s:/:.:g;
+if ($afs_admin =~ /@/) {
+    die "The administrative user must be in the same realm as the cell and\n"
+        . "no realm may be specified.\n";
+}
+
+# Determine the local cell.  This should be configured via debconf, from the
+# openafs-client configuration, when openafs-fileserver is installed.
+open(CELL, "/etc/openafs/server/ThisCell")
+    or die "Cannot open /etc/openafs/server/ThisCell: $!\n";
+my $cell = <CELL>;
+chomp $cell;
+
+# Make sure the new cell is configured in the client CellServDB.
+open(CELLSERVDB, "/etc/openafs/CellServDB")
+    or die "Cannot open /etc/openafs/CellServDB: $!\n";
+my $found = 0;
+while (<CELLSERVDB>) {
+    next unless /^>\Q$cell\E\s/;
+    while (<CELLSERVDB>) {
+        last if /^>/;
+        my ($dbserver) = split ' ';
+        if ($dbserver eq inet_ntoa($ip)) {
+            $found = 1;
+            last;
+        }
+    }
+    last;
+}
+unless ($found) {
+    print "\n";
+    print "The new cell $cell is not configured in /etc/openafs/CellServDB\n";
+    print "Add configuration like:\n\n";
+    print ">$cell\n";
+    print inet_ntoa($ip), "\t\t\t#$server\n\n";
+    print "to that file before continuing.\n";
+    exit(1);
+}
+
+# Write out a new CellServDB for the local cell containing only this server.
+if (-f "/etc/openafs/server/CellServDB") {
+    print "/etc/openafs/server/CellServDB already exists, renaming to .old\n";
+    rename("/etc/openafs/server/CellServDB",
+           "/etc/openafs/server/CellServDB.old")
+        or die "Cannot rename /etc/openafs/server/CellServDB: $!\n";
+}
+open(CELLSERVDB, "> /etc/openafs/server/CellServDB")
+    or die "Cannot create /etc/openafs/server/CellServDB: $!\n";
+print CELLSERVDB ">$cell\n";
+print CELLSERVDB inet_ntoa($ip), "\t\t\t#$server\n";
+close CELLSERVDB or die "Cannot write to /etc/openafs/server/CellServDB: $!\n";
+
+# Now, we should be able to start bos and add the admin user.
+run("service openafs-fileserver start");
+$shutdown_needed = 1;
+run("bos adduser $server $afs_admin -localauth");
+unwind("bos removeuser $server $afs_admin -localauth");
+
+# Create the initial protection database using pt_util.  This is safer than
+# the standard mechanism of starting the cell in noauth mode until the first
+# user has been created.
+if (-f "/var/lib/openafs/db/prdb.DB0") {
+    warn "ERROR: Protection database already exists; cell already partially\n";
+    warn "ERROR: created.   If you do not want the current database, remove\n";
+    warn "ERROR: all files in /var/lib/openafs/db and then run this program\n";
+    warn "ERROR: again.\n";
+    exit(1);
+}
+print "\nCreating initial protection database.  This will print some errors\n";
+print "about an id already existing and a bad ubik magic.  These errors can\n";
+print "be safely ignored.\n\n";
+open(PRDB, "| pt_util -p /var/lib/openafs/db/prdb.DB0 -w")
+    or die "Unable to start pt_util: $!\n";
+print PRDB "$afs_admin 128/20 1 -204 -204\n";
+print PRDB "system:administrators 130/20 -204 -204 -204\n";
+print PRDB " $afs_admin 1\n";
+close PRDB;
+unwind("rm /var/lib/openafs/db/prdb*");
+print "\n";
+
+# We should now be able to start ptserver and vlserver.
+run("bos create $server ptserver simple /usr/lib/openafs/ptserver -localauth");
+unwind("bos delete $server ptserver -localauth");
+run("bos create $server vlserver simple /usr/lib/openafs/vlserver -localauth");
+unwind("bos delete $server vlserver -localauth");
+
+# Create a file server as well.
+run("bos create $server dafs dafs"
+    . " -cmd '/usr/lib/openafs/dafileserver $fs_options'"
+    . " -cmd /usr/lib/openafs/davolserver"
+    . " -cmd /usr/lib/openafs/salvageserver"
+    . " -cmd /usr/lib/openafs/dasalvager -localauth");
+unwind("bos delete $server dafs -localauth");
+
+# Make sure that there is no scheduled general restart time; it's not needed.
+run("bos setrestart $server -time never -general -localauth");
+
+# Pause for a while for ubik to catch up.
+print "Waiting for database elections: ";
+sleep(30);
+print "done.\n";
+
+# Past this point we want to control when bos shutdown happens.
+$shutdown_needed = 0;
+unwind("bos shutdown $server -localauth -wait");
+run("vos create $server a root.afs -localauth");
+unwind("vos remove $server a root.afs -localauth");
+
+# We should now be able to bring up the client (it may need root.afs to exist
+# if not using dynroot).  We override whatever default cell was configured for
+# the client, just in case it was pointing to some other cell.
+open(THIS, "> /etc/openafs/ThisCell")
+    or die "ERROR: Cannot create /etc/openafs/ThisCell: $!\n";
+print THIS "$cell\n";
+close THIS or die "ERROR: Cannot write to /etc/openafs/ThisCell: $!\n";
+run("service openafs-client force-start");
+
+# Verify that AFS has managed to start.
+my $afs_running = 0;
+open(MOUNT, "mount |") or die "ERROR: Failed to run mount: $!\n";
+while(<MOUNT>) {
+    if (m:^AFS:) {
+        $afs_running = 1;
+    }
+}
+unless ($afs_running) {
+    print "ERROR: The AFS client failed to start.\n";
+    print "ERROR: Please fix whatever problem kept it from running.\n";
+    exit(1);
+}
+print "\n";
+print "Now, get tokens as $admin in the $cell cell.\n";
+print "Then, run afs-rootvol.\n";
+
+# Success, so clear the unwind commands.
+@unwinds = ();
+
+# If we fail before all the instances are created, we need to back out of
+# everything we did as much as possible.
+END {
+    if ($shutdown_needed || @unwinds) {
+        print "\nCell setup failed, ABORTING\n";
+    }
+    system("bos shutdown $server -localauth -wait") if $shutdown_needed;
+    run(pop @unwinds) while @unwinds;
+}