diff --git a/install/descriptors-v3.xml b/install/descriptors-v3.xml
index 8f4d086845434261015c287042b08a840de3d019..9856e764054f1b0e20491801cfec9a89a15a46bd 100644
--- a/install/descriptors-v3.xml
+++ b/install/descriptors-v3.xml
@@ -3,7 +3,7 @@
FEDORA10-STD
- FBSD73-STD
+ FBSD82-STD
FreeBSD
@@ -32,6 +32,19 @@
1
4.X
+
+ Linux
+ IPTables Firewall
+ ping,ssh,ipod,isup,veths,linktest
+
+ 1
+ emulab-ops,UBUNTU10-STD-FW
+ NORMALv2
+ FW-IPTABLES
+ emulab-ops
+ 120
+ 0
+
Other
Stub descriptor for power controllers of any kind
@@ -44,6 +57,18 @@
0
0.00
+
+ FreeBSD
+ Any Version of FreeBSD
+ ping,ssh,ipod,isup,veths,veth-ne,veth-en,mlinks,linktest,linkdelays,vlans
+ FreeBSD
+ 1
+ NORMAL
+ FBSD-STD
+ emulab-ops
+ 150
+ 1
+
FreeBSD
NewNode (FreeBSD) in an MFS
@@ -58,18 +83,6 @@
1
6.2
-
- FreeBSD
- Any Version of FreeBSD
- ping,ssh,ipod,isup,veths,veth-ne,veth-en,mlinks,linktest,linkdelays,vlans
- FreeBSD
- 1
- NORMAL
- FBSD-STD
- emulab-ops
- 150
- 1
-
Linux
Any of RedHat Linux
@@ -114,17 +127,32 @@
FreeBSD
- FreeBSD 7.3
+ FreeBSD 8.2 32-bit version
emulab-ops
1
- FBSD73-STD
+ FBSD82-STD
1
2
NORMALv2
- ping,ssh,ipod,isup,mlinks,linktest,linkdelays,vlans
- /usr/testbed/images/FBSD73-STD.ndz
+ ping,ssh,ipod,isup,mlinks,linktest,vlans
+ /usr/testbed/images/FBSD82-STD.ndz
emulab-ops
0
- 7.3
+ 8.2
+
+
+ Linux
+ Firewall image based on ubuntu 10
+ emulab-ops
+ 1
+ UBUNTU10-STD-FW
+ 2
+ 2
+ NORMALv2
+ ping,ssh,ipod,isup,linktest
+ /proj/emulab-ops/images/UBUNTU10-STD-FW.ndz
+ emulab-ops
+ 1
+ 10
diff --git a/install/dump-descriptors.in b/install/dump-descriptors.in
index e239136da8d98e802e52aec788ff162539fb1400..a8654e6b876119f1844b02c27dbe82c754525374 100644
--- a/install/dump-descriptors.in
+++ b/install/dump-descriptors.in
@@ -20,10 +20,11 @@ sub usage()
print STDERR " -m dump just the MFS descriptors.\n";
print STDERR " -v 1 first generation STD images (FBSD410, RHL90)\n";
print STDERR " -v 2 second generation STD images (FBSD62, FC6)\n";
- print STDERR "Default version is 1.\n";
+ print STDERR " -v 3 second generation STD images (FBSD73, FEDORA10)\n";
+ print STDERR "Default version is 2.\n";
exit(-1);
}
-my $version = 1;
+my $version = 2;
my $mfsonly = 0;
my $images;
@@ -39,11 +40,21 @@ my %imagenames = (
# included here to resolve nextosid entries for FW-IPFW and FBSD-JAIL
"2" => ['FBSD62+FC6-STD', 'FBSD62-STD', 'FC6-STD', 'FBSD410-STD',
'FBSD410-IPFW2', 'UBUNTU10-STD-FW'],
+ # No longer using combined images.
+ # The UBUNTU10 image is for FW-IPTABLES link.
+ "3" => ['FBSD82-STD', 'FEDORA10-STD', 'UBUNTU10-STD-FW'],
);
-my @osnames = ('FREEBSD-MFS', 'FRISBEE-MFS', 'NEWNODE-MFS',
- 'OPSNODE-BSD', 'FW-IPFW', 'FW-IPFW2', 'FW-IPTABLES',
- 'RHL-STD', 'FBSD-STD', 'FBSD-JAIL', 'POWER-CONTROLLER');
+my %osnames = (
+ "1" => ['FREEBSD-MFS', 'FRISBEE-MFS', 'NEWNODE-MFS',
+ 'OPSNODE-BSD', 'FW-IPFW', 'FW-IPFW2', 'FW-IPTABLES',
+ 'RHL-STD', 'FBSD-STD', 'FBSD-JAIL', 'POWER-CONTROLLER'],
+ "2" => ['FREEBSD-MFS', 'FRISBEE-MFS', 'NEWNODE-MFS',
+ 'OPSNODE-BSD', 'FW-IPFW', 'FW-IPFW2', 'FW-IPTABLES',
+ 'RHL-STD', 'FBSD-STD', 'FBSD-JAIL', 'POWER-CONTROLLER'],
+ "3" => ['FREEBSD-MFS', 'FRISBEE-MFS', 'NEWNODE-MFS', 'FW-IPTABLES',
+ 'OPSNODE-BSD', 'RHL-STD', 'FBSD-STD', 'POWER-CONTROLLER'],
+);
my @osids = ();
@@ -59,6 +70,10 @@ my %mappings = (
"2" => {
"RHL-STD" => "FC6-STD",
"FBSD-STD" => "FBSD62-STD",
+ },
+ "3" => {
+ "RHL-STD" => "FEDORA10-STD",
+ "FBSD-STD" => "FBSD82-STD",
}
);
@@ -120,7 +135,7 @@ elsif (defined($images)) {
$version = 0;
$mfsonly = 0;
%mappings = ();
- @osnames = ();
+ %osnames = ("$version" => []);
%imagenames = ("$version" => $images);
}
usage()
@@ -159,7 +174,7 @@ foreach my $imagename (@{$imagenames{$version}}) {
#
# And the OSs
#
-foreach my $osname (@osnames) {
+foreach my $osname (@{$osnames{$version}}) {
my $osinfo = OSinfo->Lookup("$protoproj,$osname");
if (!defined($osinfo)) {
fatal("Cannot find os descriptor for $osname");
diff --git a/install/genirack-imageinfo.xml b/install/genirack-imageinfo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef3dffaefaef66dd07195aa6fa9d05c6d6b31f0
--- /dev/null
+++ b/install/genirack-imageinfo.xml
@@ -0,0 +1,7 @@
+
+
+ 2012-02-29 00:00:00Z
+ http://www.emulab.net/downloads/images-STD/FBSD82-STD.ndz
+ http://www.emulab.net/downloads/images-STD/FBSD82-STD.xml
+
+
diff --git a/install/phases/boss/mfs b/install/phases/boss/mfs
index d6fa849636931cc8c4cdd12eb911d9ddb6ad4d2a..6be7fba5805b9d9b757dfca3a00079131f66857d 100755
--- a/install/phases/boss/mfs
+++ b/install/phases/boss/mfs
@@ -137,6 +137,7 @@ sub MungeMfsRoot($)
my $tftpdir = shift;
my $MFSROOT = "$TFTP_DIR/$tftpdir/boot/mfsroot";
my $status = 0;
+ my @status = ();
Phase "Munge", "Munging the $tftpdir root file system", sub {
PhaseSkip("already munged")
@@ -167,8 +168,10 @@ sub MungeMfsRoot($)
ExecQuiet("cp -p $ETCDIR/emulab.pem $ETCDIR/client.pem ".
" /mnt/etc/emulab") ||
ExecQuiet("cp -p $IMAGEKEYS_DIR/* /mnt/etc/ssh") ||
- ExecQuiet("cp -p $ZONEINFO/$OURTIMEZONE /mnt/etc/localtime")) {
+ ExecQuiet("cp -p $ZONEINFO/$OURTIMEZONE /mnt/etc/localtime") ||
+ ExecQuiet("cp /dev/null /mnt/.localized")) {
$status = 1;
+ goto done;
}
#
@@ -179,11 +182,17 @@ sub MungeMfsRoot($)
# We should have a more general way to set the console on a per
# node basis.
#
- if ($MFSCONSOLE eq "vga") {
- ExecQuietFatal("cp /dev/null /mnt/etc/emulab/isvgaonly");
+ if ($MFSCONSOLE eq "vga" &&
+ ExecQuiet("cp /dev/null /mnt/etc/emulab/isvgaonly")) {
+ $status = 1;
+ goto done;
}
-
+
done:
+ # Save actual error till after unmounting the mfs.
+ if ($status) {
+ @output = libinstall::LastOutput();
+ }
ExecQuietFatal("umount /mnt");
if ($FBSD_MAJOR >= 5) {
ExecQuietFatal("mdconfig -d -u 2");
@@ -192,7 +201,7 @@ sub MungeMfsRoot($)
ExecQuietFatal("vnconfig -u vn1");
}
if ($status) {
- my $msg = join(' ', libinstall::LastOutput());
+ my $msg = join(' ', @output);
PhaseFail("Unable to execute: '$msg'");
}
PhaseSucceed("Munged");
diff --git a/utils/GNUmakefile.in b/utils/GNUmakefile.in
index d78af1697571f13df13b1da737485523c6bb6a26..55393d95e2161a91c34ab60462a92da246703cc3 100644
--- a/utils/GNUmakefile.in
+++ b/utils/GNUmakefile.in
@@ -1,6 +1,6 @@
#
# EMULAB-COPYRIGHT
-# Copyright (c) 2000-2011 University of Utah and the Flux Group.
+# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# All rights reserved.
#
@@ -27,7 +27,7 @@ SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
anonsendmail epmodeset fixexpinfo node_traffic \
dumpdescriptor subboss_tftpboot_sync testbed-control \
archive-expinfo grantfeature emulabfeature addblob readblob \
- prereserve grantimage
+ prereserve grantimage getimages
WEB_SBIN_SCRIPTS= webnewnode webdeletenode webspewconlog webarchive_list \
webwanodecheckin webspewimage
diff --git a/utils/getimages.in b/utils/getimages.in
new file mode 100644
index 0000000000000000000000000000000000000000..a482f962110ce7193725286f1703145f5d437a15
--- /dev/null
+++ b/utils/getimages.in
@@ -0,0 +1,201 @@
+#!/usr/bin/perl -w
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2003-2012 University of Utah and the Flux Group.
+# All rights reserved.
+#
+use strict;
+use English;
+use Getopt::Std;
+use XML::Simple;
+use Date::Parse;
+use Time::Local;
+use Data::Dumper;
+use File::Temp qw(tempfile);
+
+#
+# Checkin at the master (Utah) to see if we should download and install
+# any new images
+#
+sub usage()
+{
+ print STDERR "Usage: getimages\n";
+ print STDERR " -h This message\n";
+ print STDERR " -n Impotent mode; just check and report.\n";
+ exit(-1);
+}
+my $optlist = "hndt:";
+my $debug = 0;
+my $impotent = 0;
+my $testfile;
+
+# Protos
+sub fatal($);
+
+#
+# Configure variables
+#
+my $TB = "@prefix@";
+my $METAURL = "http://www.emulab.net/genirack-imageinfo.xml";
+my $FETCH = "/usr/bin/fetch";
+my $metadata = "/tmp/imageinfo-$$.xml";
+my $NEWIMAGE_EZ = "$TB/bin/newimageid_ez";
+
+#
+# Testbed Support libraries
+#
+use lib "@prefix@/lib";
+use emdb;
+use Image;
+use OSinfo;
+use libaudit;
+use EmulabConstants;
+
+#
+# Turn off line buffering on output
+#
+$| = 1;
+
+#
+# Untaint the path
+#
+$ENV{'PATH'} = "/bin:/sbin:/usr/bin:";
+
+#
+# Parse command arguments. Once we return from getopts, all that should be
+# left are the required arguments.
+#
+my %options = ();
+if (! getopts($optlist, \%options)) {
+ usage();
+}
+if (defined($options{'h'})) {
+ usage();
+}
+if (defined($options{'n'})) {
+ $impotent = 1;
+}
+if (defined($options{'d'})) {
+ $debug = 1;
+}
+if (defined($options{'t'})) {
+ $testfile = $options{'t'};
+}
+usage()
+ if (@ARGV);
+
+# Only root.
+if ($UID && !$impotent) {
+ die("*** $0:\n".
+ " Must run this as root!\n");
+}
+
+#
+# Fetch the metadata, which tells what to do.
+#
+if (!defined($testfile)) {
+ print "Fetching metadata from the server\n"
+ if ($debug);
+ system("$FETCH -o $metadata $METAURL") == 0
+ or fatal("Could not fetch $METAURL");
+}
+else {
+ $metadata = $testfile;
+}
+
+#
+# Must wrap the parser in eval since it exits on error.
+#
+my $xmlparse = eval { XMLin($metadata,
+ VarAttr => 'name',
+ ForceArray => ['image'],
+ ContentKey => '-content',
+ SuppressEmpty => undef); };
+fatal($@)
+ if ($@);
+
+#
+#
+#
+foreach my $imageid (keys(%{ $xmlparse->{'image'} })) {
+ my $attributes = $xmlparse->{'image'}->{$imageid}->{'attribute'};
+
+ if ($debug) {
+ print STDERR Data::Dumper->Dump([$attributes], [$imageid]);
+ }
+
+ my $metaurl = $attributes->{'metaurl'};
+ my $imageurl = $attributes->{'imageurl'};
+ my $modtime = timegm(strptime($attributes->{'modtime'}));
+
+ #
+ # If we have an entry in the DB, we use the created/updated stamps
+ # to determine if we need to download a new version.
+ #
+ # Lookup will sanity check the imageid string.
+ #
+ my $image = Image->Lookup(TBOPSPID(), $imageid);
+ if (defined($image)) {
+ my $lastmod;
+
+ print "Local descriptor found: $image\n";
+ if (defined($image->updated())) {
+ $lastmod = timelocal(strptime($image->updated()));
+ }
+ else {
+ $lastmod = timelocal(strptime($image->created()));
+ }
+ if ($lastmod >= $modtime) {
+ print "Image has not changed, skipping ...\n";
+ next;
+ }
+ }
+ print "Image has changed, downloading ...\n";
+
+ my ($fh, $metafilename) = tempfile(UNLINK => !$debug);
+ fatal("Could not create temporary file")
+ if (!defined($fh));
+ close($fh);
+
+ #
+ # Grab the metadata file
+ #
+ print "Fetching $metaurl\n";
+ system("$FETCH -o $filename $metaurl") == 0
+ or fatal("Could not fetch $metaurl");
+
+ #
+ # Load up the descriptor if we do not have it.
+ #
+ if (!defined($image)) {
+ system("$NEWIMAGE_EZ -a $metafilename") == 0
+ or fatal("Could not create descriptor for $imageid");
+ }
+ $image = Image->Lookup(TBOPSPID(), $imageid);
+ if (!defined($image)) {
+ fatal("Could not lookup newly created descriptor for $imageid");
+ }
+
+ my $imagefilename = "$TB/images/${imageid}.ndz";
+ print "Fetching $imageurl\n";
+ system("$FETCH -o ${imagefilename}.$$ $imageurl") == 0
+ or fatal("Could not fetch $imageurl");
+ rename("${imagefilename}", "${imagefilename}.old")
+ if (-e "${imagefilename}");
+ rename("${imagefilename}.$$", "${imagefilename}") or
+ fatal("Could not rename ${imagefilename}.$$: $!");
+}
+
+exit(0);
+
+sub fatal($)
+{
+ my ($mesg) = $_[0];
+
+ unlink($metadata)
+ if (-e $metadata);
+ die("*** $0:\n".
+ " $mesg\n");
+}
+
+