2 # Copyright (C) 2000 by Sam Hartman
3 # This file may be copied either under the terms of the GNU GPL or the IBM
4 # Public License either version 2 or later of the GPL or version 1.0 or later
9 use Debian::OpenAFS::ConfigUtils;
11 use Socket qw(inet_ntoa);
12 use vars qw($admin $server $requirements_met $shutdown_needed);
13 my $rl = new Term::ReadLine('afs-newcell');
17 afs-newcell - Set up initial database server for AFS cell
21 B<afs-newcell> [B<--requirements-met>] [B<--admin> admin_user]
25 This script sets up the initial AFS database and configures the first
28 The B<--requirements-met> option specifies that the initial requirements have
29 been met and that the script can proceed without displaying the initial
30 banner or asking for confirmation.
32 The B<--admin> option specifies the name of the administrative user. This
33 user will be given system:administrators and susers permission in the cell.
37 Sam Hartman <hartmans@debian.org>
41 # Flush all output immediately.
44 GetOptions ("requirements-met" => \$requirements_met, "admin=s" => \$admin);
46 unless ($requirements_met) {
50 In order to set up a new AFS cell, you must meet the following:
52 1) You need a working Kerberos realm with Kerberos4 support. You
53 should install Heimdal with KTH Kerberos compatibility or MIT
56 2) You need to create the single-DES AFS key and load it into
57 /etc/openafs/server/KeyFile. If your cell's name is the same as
58 your Kerberos realm then create a principal called afs. Otherwise,
59 create a principal called afs/cellname in your realm. The cell
60 name should be all lower case, unlike Kerberos realms which are all
61 upper case. You can use asetkey from the openafs-krb5 package, or
62 if you used AFS3 salt to create the key, the bos addkey command.
64 3) This machine should have a filesystem mounted on /vicepa. If you
65 do not have a free partition, then create a large file by using dd
66 to extract bytes from /dev/zero. Create a filesystem on this file
67 and mount it using -oloop.
69 4) You will need an administrative principal created in a Kerberos
70 realm. This principal will be added to susers and
71 system:administrators and thus will be able to run administrative
72 commands. Generally the user is a root or admin instance of some
73 administrative user. For example if jruser is an administrator then
74 it would be reasonable to create jruser/admin (or jruser/root) and
75 specify that as the user to be added in this script.
77 5) The AFS client must not be running on this workstation. It will be
78 at the end of this script.
83 $_ = $rl->readline("Do you meet these requirements? [y/n] ");
85 print "Run this script again when you meet the requirements\n";
90 die "This script should almost always be run as root. Use the\n"
91 . "--requirements-met option to run as non-root.\n";
95 # Make sure the AFS client is not already running.
96 open(MOUNT, "mount |") or die "Failed to run mount: $!\n";
99 print "The AFS client is currently running on this workstation.\n";
100 print "Please restart this script after running"
101 . " /etc/init.d/openafs-client stop\n";
107 # Make sure there is a keyfile.
108 unless ( -f "/etc/openafs/server/KeyFile") {
109 print "You do not have an AFS keyfile. Please create this using\n";
110 print "asetkey from openafs-krb5 or the bos addkey command\n";
114 # Stop the file server.
115 print "If the fileserver is not running, this may hang for 30 seconds.\n";
116 run("/etc/init.d/openafs-fileserver stop");
118 # Get the local hostname. Use the fully-qualified hostname to be safer.
119 $server = `hostname -f`;
121 my $ip = gethostbyname $server;
122 if (inet_ntoa($ip) eq '127.0.0.1') {
124 print "Your hostname $server resolves to 127.0.0.1, which AFS cannot\n";
125 print "cope with. Make sure your hostname resolves to a non-loopback\n";
126 print "IP address. (Check /etc/hosts and make sure that your hostname\n";
127 print "isn't listed on the 127.0.0.1 line. If it is, removing it from\n";
128 print "that line will probably solve this problem.)\n";
132 # Determine the admin principal.
133 $admin = $rl->readline("What administrative principal should be used? ")
136 die "Please specify an administrative user\n" unless $admin;
137 my $afs_admin = $admin;
138 $afs_admin =~ s:/:.:g;
139 if ($afs_admin =~ /@/) {
140 die "The administrative user must be in the same realm as the cell and\n"
141 . "no realm may be specified.\n";
144 # Determine the local cell. This should be configured via debconf, from the
145 # openafs-client configuration, when openafs-fileserver is installed.
146 open(CELL, "/etc/openafs/server/ThisCell")
147 or die "Cannot open /etc/openafs/server/ThisCell: $!\n";
151 # Make sure the new cell is configured in the client CellServDB.
152 open(CELLSERVDB, "/etc/openafs/CellServDB")
153 or die "Cannot open /etc/openafs/CellServDB: $!\n";
155 while (<CELLSERVDB>) {
156 next unless /^>\Q$cell\E\s/;
157 while (<CELLSERVDB>) {
159 my ($dbserver) = split ' ';
160 if ($dbserver eq inet_ntoa($ip)) {
169 print "The new cell $cell is not configured in /etc/openafs/CellServDB\n";
170 print "Add configuration like:\n\n";
172 print inet_ntoa($ip), "\n\n";
173 print "to that file before continuing.\n";
177 # Write out a new CellServDB for the local cell containing only this server.
178 if (-f "/etc/openafs/server/CellServDB") {
179 print "/etc/openafs/server/CellServDB already exists, renaming to .old\n";
180 rename("/etc/openafs/server/CellServDB",
181 "/etc/openafs/server/CellServDB.old")
182 or die "Cannot rename /etc/openafs/server/CellServDB: $!\n";
184 open(CELLSERVDB, "> /etc/openafs/server/CellServDB")
185 or die "Cannot create /etc/openafs/server/CellServDB: $!\n";
186 print CELLSERVDB ">$cell\n";
187 print CELLSERVDB inet_ntoa($ip), "\t\t\t#$server\n";
188 close CELLSERVDB or die "Cannot write to /etc/openafs/server/CellServDB: $!\n";
190 # Now, we should be able to start bos and add the admin user.
191 run("/etc/init.d/openafs-fileserver start");
192 $shutdown_needed = 1;
193 run("bos adduser $server $afs_admin -localauth");
194 unwind("bos removeuser $server $afs_admin -localauth");
196 # Create the initial protection database using pt_util. This is safer than
197 # the standard mechanism of starting the cell in noauth mode until the first
198 # user has been created.
199 if (-f "/var/lib/openafs/db/prdb.DB0") {
200 warn "ERROR: Protection database already exists; cell already partially\n";
201 warn "ERROR: created. If you do not want the current database, remove\n";
202 warn "ERROR: all files in /var/lib/openafs/db and then run this program\n";
203 warn "ERROR: again.\n";
206 print "\nCreating initial protection database. This will print some errors\n";
207 print "about an id already existing and a bad ubik magic. These errors can\n";
208 print "be safely ignored.\n\n";
209 open(PRDB, "| pt_util -p /var/lib/openafs/db/prdb.DB0 -w")
210 or die "Unable to start pt_util: $!\n";
211 print PRDB "$afs_admin 128/20 1 -204 -204\n";
212 print PRDB "system:administrators 130/20 -204 -204 -204\n";
213 print PRDB " $afs_admin 1\n";
215 unwind("rm /var/lib/openafs/db/prdb*");
218 # We should now be able to start ptserver and vlserver.
219 run("bos create $server ptserver simple /usr/lib/openafs/ptserver -localauth");
220 unwind("bos delete $server ptserver -localauth");
221 run("bos create $server vlserver simple /usr/lib/openafs/vlserver -localauth");
222 unwind("bos delete $server vlserver -localauth");
224 # Create a file server as well.
225 run("bos create $server fs fs"
226 . " -cmd /usr/lib/openafs/fileserver"
227 . " -cmd /usr/lib/openafs/volserver"
228 . " -cmd /usr/lib/openafs/salvager -localauth");
229 unwind("bos delete $server fs -localauth");
231 # Pause for a while for ubik to catch up.
232 print "Waiting for database elections: ";
236 # Past this point we want to control when bos shutdown happens.
237 $shutdown_needed = 0;
238 unwind("bos shutdown $server -localauth -wait");
239 run("vos create $server a root.afs -localauth");
240 unwind("vos remove $server a root.afs -localauth");
242 # We should now be able to bring up the client (it may need root.afs to exist
243 # if not using dynroot). We override whatever default cell was configured for
244 # the client, just in case it was pointing to some other cell.
245 open(THIS, "> /etc/openafs/ThisCell")
246 or die "ERROR: Cannot create /etc/openafs/ThisCell: $!\n";
247 print THIS "$cell\n";
248 close THIS or die "ERROR: Cannot write to /etc/openafs/ThisCell: $!\n";
249 run("/etc/init.d/openafs-client force-start");
251 # Verify that AFS has managed to start.
253 open(MOUNT, "mount |") or die "ERROR: Failed to run mount: $!\n";
259 unless ($afs_running) {
260 print "ERROR: The AFS client failed to start.\n";
261 print "ERROR: Please fix whatever problem kept it from running.\n";
265 print "Now, get tokens as $admin in the $cell cell.\n";
266 print "Then, run afs-rootvol.\n";
268 # Success, so clear the unwind commands.
271 # If we fail before all the instances are created, we need to back out of
272 # everything we did as much as possible.
274 if ($shutdown_needed || @unwinds) {
275 print "\nCell setup failed, ABORTING\n";
277 system("bos shutdown $server -localauth -wait") if $shutdown_needed;
278 run(pop @unwinds) while @unwinds;