mfs 5.89 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
#
# 
#
use strict;
use libinstall;
use installvars;

my $MFSTARBALL	    = "tftpboot-elabinelab.tar.gz";
my $MFSURL	    = "http://www.emulab.net/downloads/$MFSTARBALL";
my $MFSVERSION      = "62";
11
my $MFSCONSOLE      = $NODECONSOLE;
12
my $MFSDESCRIPTORS  = "$TOP_SRCDIR/install/descriptors-mfs.xml";
13
my $ZONEINFO	    = "/usr/share/zoneinfo";
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

sub Install($$$)
{
    my ($server, $isupdate, $impotent) = @_;

    # Replace if this script does an update for ip/domain.
    return 0
	if ($isupdate);

    if ($FBSD_MAJOR >= 7.2) {
	$MFSVERSION = "72";
    }

    Phase "mfs", "Setting up MFSs", sub {
	my $localfile = "$TFTP_DIR/tftpboot.tar.gz";
	
	Phase "mfsfetch", "Fetching MFS tarball", sub {
	    DoneIfExists($localfile);
	    FetchFileFatal($MFSURL, $localfile);
	};
	Phase "mfsunpack", "Unpacking MFS tarball", sub {
	    DoneIfExists("$TFTP_DIR/README");
	    ExecQuietFatal("$TAR xzf $localfile -C $TFTP_DIR");
	};
	#
	# Its the generic stuff; must localize.
	#
	my $fv = $MFSVERSION;
	if (! -e "$TFTP_DIR/freebsd${fv}") {
	    $fv = "47";
	}
	my $pdir = ".";
	if (-d "$TFTP_DIR/pxeboot${fv}") {
	    $pdir = "pxeboot${fv}";
	}
	my $cons = $MFSCONSOLE;
	if (! -e "$TFTP_DIR/$pdir/pxeboot.emu-${cons}") {
	    $cons = "sio";
	}
	Phase "pxemv", "Using ${cons} version of pxeboot", sub {
	    DoneIfExists("$TFTP_DIR/pxeboot.emu");
	    ExecQuietFatal("cd $TFTP_DIR; ".
			   "$MV $pdir/pxeboot.emu-${cons} pxeboot.emu");
	};
	Phase "freemv", "Using freebsd${fv} version of admin MFS", sub {
	    DoneIfExists("$TFTP_DIR/freebsd");
	    ExecQuietFatal("cd $TFTP_DIR; $MV freebsd${fv} freebsd");
	};
	Phase "frismv", "Using frisbee${fv} version of disk load MFS", sub {
	    DoneIfExists("$TFTP_DIR/frisbee");
	    ExecQuietFatal("cd $TFTP_DIR; $MV frisbee${fv} frisbee");
	};
	#
	# Older tarballs didn't have FBSD-specific versions of newnode MFS.
	#
	if (! -e "$TFTP_DIR/freebsd.newnode") {
	    Phase "newnode", "Using freebsd${fv} version of newnode MFS", sub {
		DoneIfExists("$TFTP_DIR/freebsd.newnode");
		ExecQuietFatal("cd $TFTP_DIR; ".
			       "$MV freebsd${fv}.newnode freebsd.newnode");
	    };
	}

	#
	# Copy the inner SSL cert and root's public ssh keys to the MFSes
	# so that they will talk to the inner boss properly.
	# At Berkeley the frisbee MFS copies these to disk images,
	# needing changes to slicefix, which always needs to be run now.
	#
	MungeMfsRoot("frisbee");
	MungeMfsRoot("freebsd");
	MungeMfsRoot("freebsd.newnode");

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	#
	# Fix the console device in the MFSes
	#
	Phase "mfsconsole", "Setting the console for MFSes", sub {	
	    my %consmap = (
		"sio"  => "com",
		"sio2" => "com",
		"vga"  => "vid",
		"null" => "null"
	    );
	    my $consdev = $consmap{$cons} . "console";
	    foreach my $mfs ("frisbee", "freebsd", "freebsd.newnode") {
		AppendToFileFatal("$TFTP_DIR/$mfs/boot/loader.conf.orig",
				  "console=\"$consdev\"");
	    }
	};

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	#
	# Finally, create the compressed versions of the MFS files
	#
	Phase "prepare1", "Compressing the frisbee MFS", sub {
	    DoneIfExists("$TFTP_DIR/frisbee/boot/mfsroot.gz");
	    ExecQuietFatal("cd $TFTP_DIR/frisbee/boot; ./prepare");
	};
	Phase "prepare2", "Compressing the freebsd MFS", sub {
	    DoneIfExists("$TFTP_DIR/freebsd/boot/mfsroot.gz");
	    ExecQuietFatal("cd $TFTP_DIR/freebsd/boot; ./prepare");
	};
	Phase "prepare3", "Compressing the newnode MFS", sub {
	    DoneIfExists("$TFTP_DIR/freebsd.newnode/boot/mfsroot.gz");
	    ExecQuietFatal("cd $TFTP_DIR/freebsd.newnode/boot; ./prepare");
	};

	#
Leigh B Stoller's avatar
Leigh B Stoller committed
121 122 123
	# Load the descriptors into the DB. Inside an elabinelab these are
	# already loaded, but the script will just skip over them without
	# raising an error.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
	#
	Phase "descriptors", "Loading the Image and OS IDS", sub {
	    ExecQuietFatal("cd $TOP_OBJDIR/install; ".
			   "   $SUDO -u $PROTOUSER $WAP ".
			   "   perl load-descriptors $MFSDESCRIPTORS");
	};
	PhaseSucceed("done");
    };
    return 0;
}

sub MungeMfsRoot($)
{
    my $tftpdir = shift;
    my $MFSROOT = "$TFTP_DIR/$tftpdir/boot/mfsroot";
139
    my $status  = 0;
140
    my @status  = ();
141 142 143 144 145 146 147 148 149 150 151 152 153 154

    Phase "Munge", "Munging the $tftpdir root file system", sub {
	PhaseSkip("already munged")
	    if (-e "${MFSROOT}.gz");
	
	if ($FBSD_MAJOR >= 5) {
	    ExecQuietFatal("mdconfig -a -t vnode -f $MFSROOT -u 2");
	    ExecQuietFatal("mount /dev/md2 /mnt");
	}
	else {
	    ExecQuietFatal("vnconfig -c vn1 $MFSROOT");
	    ExecQuietFatal("mount /dev/vn1 /mnt");
	}

155 156 157 158
	if (! -e "/mnt/root/.ssh" &&
	    ExecQuiet("$MKDIR -m 700 /mnt/root/.ssh")) {
	    $status = 1;
	    goto done;
159
	}
160 161 162 163 164 165 166 167 168 169 170
	if ($ELABINELAB &&
	    # Combine with outer boss keys.
	    ExecQuiet("$CAT $AUTHKEYS > /mnt/root/.ssh/authorized_keys2")) {
	    $status = 1;
	    goto done;
	}
	if (ExecQuiet("cat /root/.ssh/*.pub >> /mnt/root/.ssh/authorized_keys2") ||
	    ExecQuiet("$CHMOD 600 /mnt/root/.ssh/authorized_keys2") ||
	    ExecQuiet("cp -p $ETCDIR/emulab.pem $ETCDIR/client.pem ".
		      "   /mnt/etc/emulab") ||
	    ExecQuiet("cp -p $IMAGEKEYS_DIR/* /mnt/etc/ssh") ||
171 172
	    ExecQuiet("cp -p $ZONEINFO/$OURTIMEZONE /mnt/etc/localtime") ||
	    ExecQuiet("cp /dev/null /mnt/.localized")) {
173
	    $status = 1;
174
	    goto done;
175 176
	}

177 178 179 180 181 182 183 184
	#
	# XXX tmp hack.
	# If console is VGA, create the magic file that tells slicefix
	# to ensure that serial console is disabled in any FreeBSD image
	# that is loaded (in case the machine has no serial port).
	# We should have a more general way to set the console on a per
	# node basis.
	#
185 186 187 188
	if ($MFSCONSOLE eq "vga" &&
	    ExecQuiet("cp /dev/null /mnt/etc/emulab/isvgaonly")) {
	    $status = 1;
	    goto done;
189
	}
190

191
      done:
192 193 194 195
	# Save actual error till after unmounting the mfs.
	if ($status) {
	    @output = libinstall::LastOutput();
	}
196 197 198 199 200 201 202 203
	ExecQuietFatal("umount /mnt");
	if ($FBSD_MAJOR >= 5) {
	    ExecQuietFatal("mdconfig -d -u 2");
	}
	else {
	    ExecQuietFatal("vnconfig -u vn1");
	}
	if ($status) {
204
	    my $msg = join(' ', @output);
205 206 207 208 209 210 211 212 213 214
	    PhaseFail("Unable to execute: '$msg'");
	}
	PhaseSucceed("Munged");
    };
    return 0;
}

# Local Variables:
# mode:perl
# End: