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"; ...@@ -49,6 +49,13 @@ my $nodereboot = "$TB/bin/node_reboot";
my $makeconf = "$TB/sbin/dhcpd_makeconf"; my $makeconf = "$TB/sbin/dhcpd_makeconf";
my $nodewait = "$TB/sbin/node_statewait"; my $nodewait = "$TB/sbin/node_statewait";
my $snmpit = "$TB/bin/snmpit"; 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 # Locals
my $elabinelab; my $elabinelab;
...@@ -928,6 +935,13 @@ sub DumpDBGoo() ...@@ -928,6 +935,13 @@ sub DumpDBGoo()
or die("*** $0:\n". or die("*** $0:\n".
" Could not dump table tiplines\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. # Tar up the directory and send it over to (real) ops.
# #
......
...@@ -1108,12 +1108,23 @@ sub SetupBossNode() ...@@ -1108,12 +1108,23 @@ sub SetupBossNode()
GetEmulabSource("${TBDIR}/testbed/src"); GetEmulabSource("${TBDIR}/testbed/src");
print "Copying over initial dbstate from /proj\n"; print "Copying over initial dbstate from /proj\n";
mysystem("mkdir ${TBDIR}/testbed/stuff"); my $expdir = "/proj/$pid/exp/$eid";
mysystem("cp -fp /proj/$pid/exp/$eid/dbstate.tar.gz ". my $stuffdir = "${TBDIR}/testbed/stuff";
" ${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. # 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). # Stash the IP of the outer emulab for tmcc (and script above).
...@@ -1364,12 +1375,11 @@ sub SetupBossNode() ...@@ -1364,12 +1375,11 @@ sub SetupBossNode()
# of boss install too. # of boss install too.
# #
print "Copying over tftpboot tar file from web server and unpacking\n"; 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/". "http://${bossname}/downloads/".
$emulabconfig{"MFSTARBALL"}); $emulabconfig{"MFSTARBALL"});
mysystem("tar xzf ${TBDIR}/testbed/stuff/tftpboot.tar.gz ". mysystem("tar xzf $stuffdir/tftpboot.tar.gz -C /tftpboot");
" -C /tftpboot");
# #
# Its the generic stuff; must localize. # Its the generic stuff; must localize.
...@@ -1418,7 +1428,7 @@ sub SetupBossNode() ...@@ -1418,7 +1428,7 @@ sub SetupBossNode()
# inner boss to invoke the XMLRPC server on the outer boss for # inner boss to invoke the XMLRPC server on the outer boss for
# doing things like power control, vlan setup, etc. # 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 # Copy the inner ssl cert and root's public ssh keys to the mfs's
...@@ -1439,8 +1449,7 @@ sub SetupBossNode() ...@@ -1439,8 +1449,7 @@ sub SetupBossNode()
# Unpack the initial DB contents and load it into the DB. # Unpack the initial DB contents and load it into the DB.
# #
mysystem("mkdir /tmp/dbstate.$$"); mysystem("mkdir /tmp/dbstate.$$");
mysystem("tar xzf ${TBDIR}/testbed/stuff/dbstate.tar.gz ". mysystem("tar xzf $stuffdir/dbstate.tar.gz -C /tmp/dbstate.$$");
" -C /tmp/dbstate.$$");
opendir(DIR, "/tmp/dbstate.$$") or opendir(DIR, "/tmp/dbstate.$$") or
SetupFatal("Cannot opendir /tmp/dbstate.$$: $!"); SetupFatal("Cannot opendir /tmp/dbstate.$$: $!");
......
...@@ -33,6 +33,7 @@ sub debug(@); ...@@ -33,6 +33,7 @@ sub debug(@);
my $debug = 0; my $debug = 0;
my $sql = 1; my $sql = 1;
my $quiet = 0; my $quiet = 0;
my $ignore_tables = 0;
# #
# Return value - number of differences between the two files # Return value - number of differences between the two files
...@@ -43,7 +44,7 @@ my $diff = 0; ...@@ -43,7 +44,7 @@ my $diff = 0;
# Process command-line args # Process command-line args
# #
my %opt; my %opt;
getopts('hdsq', \%opt); getopts('hdsqt', \%opt);
if ($opt{h}) { if ($opt{h}) {
exit &usage; exit &usage;
} }
...@@ -58,7 +59,9 @@ if ($opt{q}) { ...@@ -58,7 +59,9 @@ if ($opt{q}) {
$sql = 0; $sql = 0;
$debug = 0; $debug = 0;
} }
if ($opt{t}) {
$ignore_tables = 1;
}
if (@ARGV != 2) { if (@ARGV != 2) {
exit &usage exit &usage
...@@ -289,7 +292,8 @@ sub compare_tables($$) { ...@@ -289,7 +292,8 @@ sub compare_tables($$) {
# Removed tables are easy to handle # Removed tables are easy to handle
# #
foreach my $table (@$removed) { foreach my $table (@$removed) {
$diff++; $diff++
if (!$ignore_tables);
if (!$quiet) { print "# Table $table was removed\n"; } if (!$quiet) { print "# Table $table was removed\n"; }
if ($sql) { print "DROP TABLE $table;\n\n"; } if ($sql) { print "DROP TABLE $table;\n\n"; }
} }
...@@ -298,7 +302,8 @@ sub compare_tables($$) { ...@@ -298,7 +302,8 @@ sub compare_tables($$) {
# #
# #
foreach my $table (@$added) { foreach my $table (@$added) {
$diff++; $diff++
if (!$ignore_tables);
if (!$quiet) { print "# Table $table was added\n"; } if (!$quiet) { print "# Table $table was added\n"; }
if ($sql) { if ($sql) {
print "CREATE TABLE $table (\n"; print "CREATE TABLE $table (\n";
...@@ -592,6 +597,7 @@ sub usage() { ...@@ -592,6 +597,7 @@ sub usage() {
print "-h This message\n"; print "-h This message\n";
print "-s Summary: Don't print SQL statments to apply changes\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 "-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"; print "-d Turn on debugging output\n";
return 1; 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