Commit b54ae4da authored by Russ Fish's avatar Russ Fish

Check that the inner elab db schema isn't out of date wrt the outer one,

  since we import a bunch of dumped db state from the outer to the inner db.
  Added/removed columns in the schema misalign row data, causing much chaos.

tbsetup/elabinelab.in - Dump and send the outer db schema with the db state.
  Runs mysqldump just like schemacheck does.

tmcd/common/config/rc.mkelab - Add the schema check using schemadiff.

utils/schemadiff - Add an option to ignore table creates and drops.
parent 6fa2180e
......@@ -49,6 +49,13 @@ my $nodereboot = "$TB/bin/node_reboot";
my $makeconf = "$TB/sbin/dhcpd_makeconf";
my $nodewait = "$TB/sbin/node_statewait";
my $snmpit = "$TB/bin/snmpit";
my $isvers5 = system("mysql -V | egrep -q -s 'Distrib 5.'") == 0;
my $extraopts = ($isvers5 ? "--skip-quote-names" : "");
#
# XXX: Requires that mysqldump be in caller's $PATH - probably an OK
# assumption, but maybe not always
#
my $mysqldump = "mysqldump -d $extraopts $DBNAME";
# Locals
my $elabinelab;
......@@ -928,6 +935,13 @@ sub DumpDBGoo()
or die("*** $0:\n".
" Could not dump table tiplines\n");
#
# Dump the DB schema too, so we can check in the inner Elab that this data
# is compatible with the sql/database-create.sql schema file there, *before*
# loading it into the db. Added/removed columns would misalign row data.
#
system("$mysqldump 2> /dev/null > $expdir/outer_db_schema");
#
# Tar up the directory and send it over to (real) ops.
#
......
......@@ -1108,12 +1108,23 @@ sub SetupBossNode()
GetEmulabSource("${TBDIR}/testbed/src");
print "Copying over initial dbstate from /proj\n";
mysystem("mkdir ${TBDIR}/testbed/stuff");
mysystem("cp -fp /proj/$pid/exp/$eid/dbstate.tar.gz ".
" ${TBDIR}/testbed/stuff");
my $expdir = "/proj/$pid/exp/$eid";
my $stuffdir = "${TBDIR}/testbed/stuff";
mysystem("mkdir $stuffdir");
mysystem("cp -fp $expdir/dbstate.tar.gz $stuffdir");
mysystem("cp -fp $expdir/outer_db_schema $stuffdir");
if (!$NOSETUP) {
print "Check for db schema mismatch before we go any further\n";
my $testbed_srcdir = "${TBDIR}/testbed/src";
my $schemadiff = "$testbed_srcdir/utils/schemadiff";
my $master_schema = "$testbed_srcdir/sql/database-create.sql";
my $outer_schema = "$stuffdir/outer_db_schema";
mysystem("$schemadiff -st $master_schema $outer_schema");
}
# Copy over creators ssl certificate for XMLRPC. See below.
mysystem("cp -fp ~${creator}/.ssl/emulab.pem ${TBDIR}/testbed/stuff");
mysystem("cp -fp ~${creator}/.ssl/emulab.pem $stuffdir");
#
# Stash the IP of the outer emulab for tmcc (and script above).
......@@ -1364,12 +1375,11 @@ sub SetupBossNode()
# of boss install too.
#
print "Copying over tftpboot tar file from web server and unpacking\n";
mysystem("wget -q -O ${TBDIR}/testbed/stuff/tftpboot.tar.gz ".
mysystem("wget -q -O $stuffdir/tftpboot.tar.gz ".
"http://${bossname}/downloads/".
$emulabconfig{"MFSTARBALL"});
mysystem("tar xzf ${TBDIR}/testbed/stuff/tftpboot.tar.gz ".
" -C /tftpboot");
mysystem("tar xzf $stuffdir/tftpboot.tar.gz -C /tftpboot");
#
# Its the generic stuff; must localize.
......@@ -1418,7 +1428,7 @@ sub SetupBossNode()
# inner boss to invoke the XMLRPC server on the outer boss for
# doing things like power control, vlan setup, etc.
#
mysystem("cp -p ${TBDIR}/testbed/stuff/emulab.pem $RPCCERT");
mysystem("cp -p $stuffdir/emulab.pem $RPCCERT");
#
# Copy the inner ssl cert and root's public ssh keys to the mfs's
......@@ -1439,8 +1449,7 @@ sub SetupBossNode()
# Unpack the initial DB contents and load it into the DB.
#
mysystem("mkdir /tmp/dbstate.$$");
mysystem("tar xzf ${TBDIR}/testbed/stuff/dbstate.tar.gz ".
" -C /tmp/dbstate.$$");
mysystem("tar xzf $stuffdir/dbstate.tar.gz -C /tmp/dbstate.$$");
opendir(DIR, "/tmp/dbstate.$$") or
SetupFatal("Cannot opendir /tmp/dbstate.$$: $!");
......
......@@ -33,6 +33,7 @@ sub debug(@);
my $debug = 0;
my $sql = 1;
my $quiet = 0;
my $ignore_tables = 0;
#
# Return value - number of differences between the two files
......@@ -43,7 +44,7 @@ my $diff = 0;
# Process command-line args
#
my %opt;
getopts('hdsq', \%opt);
getopts('hdsqt', \%opt);
if ($opt{h}) {
exit &usage;
}
......@@ -58,7 +59,9 @@ if ($opt{q}) {
$sql = 0;
$debug = 0;
}
if ($opt{t}) {
$ignore_tables = 1;
}
if (@ARGV != 2) {
exit &usage
......@@ -289,7 +292,8 @@ sub compare_tables($$) {
# Removed tables are easy to handle
#
foreach my $table (@$removed) {
$diff++;
$diff++
if (!$ignore_tables);
if (!$quiet) { print "# Table $table was removed\n"; }
if ($sql) { print "DROP TABLE $table;\n\n"; }
}
......@@ -298,7 +302,8 @@ sub compare_tables($$) {
#
#
foreach my $table (@$added) {
$diff++;
$diff++
if (!$ignore_tables);
if (!$quiet) { print "# Table $table was added\n"; }
if ($sql) {
print "CREATE TABLE $table (\n";
......@@ -592,6 +597,7 @@ sub usage() {
print "-h This message\n";
print "-s Summary: Don't print SQL statments to apply changes\n";
print "-q Quiet: Don't print anything, just return a value\n";
print "-t Ignore table creates and drops\n";
print "-d Turn on debugging output\n";
return 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment