Commit 7c38809d authored by Leigh Stoller's avatar Leigh Stoller

rspecs are so passe ...

Redo the rspectogenilib converter with the goal of supporting both
translation *and* regression testing. A new library is responsible for
taking the output of libXML and creating a data structure representing
the rspec. While this is being done, we look for any constructs or
attributes we cannot handle with geni-lib and report that as an error;
we are not going to convert an rspec unless we can do it correctly. and
completely.

Regression testing is done with another part of this library, that knows
how to compare each element of two rspecs. Basically start at the root
and compare all the way down, failing if the two "parses" of the XML are
not equal at any level.

rspectogenilib now has an option that does regression testing by running
the new geni-lib and comparing the resulting rspec against the original.

On the UI side, there is a new button on existing rspec based
profiles (currently only for admin and studs) called "Convert to
geni-lib" that runs the converter to convert the profile to geni-lib.
The user does not have to accept the new script of course.

However, a converted profile is marked in the database, and the user can
still use Jacks on it, we just run rspectogenilib geni-lib again on the
new rspec. If the user edits the geni-lib, we switch back to normal
geni-lib (clear the flag) when the new version is saved, and Jacks is
once again read-only. This is explained in the UI, and is one of the
things people need to give comment on.

There is also a mode on the Create Profile page for converting new rspec
based profiles to geni-lib, but that is fully turned off for now, we can
get to that later.
parent 57c22f07
......@@ -468,6 +468,11 @@ sub Create($$$$$$)
$vquery .= ",repohash=" . DBQuoteSpecial($argref->{'repohash'});
$vquery .= ",repokey=" . DBQuoteSpecial($argref->{'repokey'});
}
if (exists($argref->{'portal_converted'}) &&
$argref->{'portal_converted'} ne "") {
$vquery .= ",portal_converted=" .
DBQuoteSpecial($argref->{'portal_converted'});
}
# Back to the main table.
$cquery .= ",uuid='$puuid'";
......
This diff is collapsed.
......@@ -37,7 +37,7 @@ BIN_SCRIPTS = manage_profile manage_instance manage_dataset \
SBIN_SCRIPTS = apt_daemon aptevent_daemon portal_xmlrpc apt_checkup \
portal_monitor
LIB_SCRIPTS = APT_Profile.pm APT_Instance.pm APT_Dataset.pm APT_Geni.pm \
APT_Aggregate.pm APT_Utility.pm
APT_Aggregate.pm APT_Utility.pm APT_Rspec.pm
WEB_BIN_SCRIPTS = webmanage_profile webmanage_instance webmanage_dataset \
webcreate_instance webrungenilib webns2rspec webns2genilib \
webrspec2genilib webmanage_reservations webmanage_gitrepo \
......
......@@ -187,6 +187,7 @@ my %xmlfields =
"rspec" => ["rspec", $SLOT_REQUIRED|$SLOT_UPDATE],
"script" => ["script", $SLOT_OPTIONAL|$SLOT_UPDATE],
"repourl" => ["repourl", $SLOT_OPTIONAL],
"portal_converted" => ["portal_converted", $SLOT_OPTIONAL|$SLOT_UPDATE],
);
if ($action eq "update") {
......@@ -660,12 +661,14 @@ sub ModifyProfileInternal($$$)
$webtask->newProfile($profile->uuid())
if (defined($webtask));
}
foreach my $key ("rspec", "script", "paramdefs", "repohash") {
foreach my $key ("rspec", "script", "paramdefs",
"repohash", "portal_converted") {
$profile->UpdateVersion({$key => $update_args{$key}})
if (exists($update_args{$key}));
}
}
foreach my $key ("rspec", "script", "paramdefs", "repohash") {
foreach my $key ("rspec", "script", "paramdefs",
"repohash", "portal_converted") {
delete($update_args{$key})
if (exists($update_args{$key}));
}
......@@ -780,7 +783,6 @@ sub VerifyXML($$)
$modifiers{$dbslot} = $value;
next;
}
# Now check that the value is legal.
if (! TBcheck_dbslot($value, "apt_profiles",
$dbslot, TBDB_CHECKDBSLOT_ERROR)) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -220,6 +220,12 @@ function Do_Create()
htmlspecialchars($formfields["profile_script"]) .
"</value>");
fwrite($fp, "</attribute>\n");
if (isset($formfields["portal_converted"]) &&
$formfields["portal_converted"] == "yes") {
fwrite($fp, "<attribute name='portal_converted'>");
fwrite($fp, " <value>1</value>");
fwrite($fp, "</attribute>\n");
}
}
if (isset($formfields["profile_repourl"]) &&
$formfields["profile_repourl"] != "") {
......@@ -1138,6 +1144,55 @@ function Do_ConvertClassic()
unlink($outfname);
}
#
# Convert rspec to geni-lib script.
#
function Do_ConvertRspec()
{
global $this_user, $suexec_output;
global $ajax_args;
$this_idx = $this_user->uid_idx();
$this_uid = $this_user->uid();
if (!isset($ajax_args["rspec"])) {
SPITAJAX_ERROR(1, "Missing rspec");
return;
}
$infname = tempnam("/tmp", "convertin");
$outfname = tempnam("/tmp", "convertout");
$rspecfname = tempnam("/tmp", "convertoutrspec");
$fp = fopen($infname, "w");
fwrite($fp, $ajax_args["rspec"]);
fclose($fp);
chmod($infname, 0666);
chmod($outfname, 0666);
chmod($rspecfname, 0666);
#
# Invoke the backend.
#
$retval = SUEXEC($this_uid, "nobody",
"webrspec2genilib -r -s $rspecfname -o $outfname $infname",
SUEXEC_ACTION_IGNORE);
if ($retval != 0) {
#
# All errors go to the user for now.
#
SPITAJAX_ERROR($retval, $suexec_output);
}
else {
$script = file_get_contents($outfname);
SPITAJAX_RESPONSE(array("script" => $script,
"rspec" => file_get_contents($rspecfname)));
}
unlink($infname);
unlink($outfname);
unlink($rspecfname);
}
#
# Clone a repository and send back the script or rspec.
#
......
......@@ -71,6 +71,7 @@ function SPITFORM($formfields, $errors)
$activity = 0;
$ispp = 0;
$isadmin = (ISADMIN() ? 1 : 0);
$isstud = (STUDLY() ? 1 : 0);
$canrepo = (ISADMIN() || STUDLY() ? 1 : 0);
$multisite = 1;
$cloning = 0;
......@@ -193,6 +194,7 @@ function SPITFORM($formfields, $errors)
echo " window.CANPUBLISH= $canpublish;\n";
echo " window.DISABLED= $disabled;\n";
echo " window.ISADMIN = $isadmin;\n";
echo " window.ISSTUD = $isstud;\n";
echo " window.MULTISITE = $multisite;\n";
echo " window.HISTORY = $history;\n";
echo " window.CLONING = $cloning;\n";
......@@ -368,6 +370,8 @@ if (! isset($create)) {
if ($profile->script() && $profile->script() != "") {
$defaults["profile_script"] = $profile->script();
}
$defaults["portal_converted"]
= ($profile->portal_converted() == 1 ? "yes" : "no");
# Default the project if in only one project.
if (count($projlist) == 1) {
list($project) = each($projlist);
......@@ -383,6 +387,8 @@ if (! isset($create)) {
if ($profile->script() && $profile->script() != "") {
$defaults["profile_script"] = $profile->script();
}
$defaults["portal_converted"]
= ($profile->portal_converted() == 1 ? "yes" : "no");
if ($profile->repourl() && $profile->repourl() != "") {
$defaults["profile_repourl"] = $profile->repourl();
# Need this so JS code knows when HEAD changes.
......
......@@ -138,6 +138,7 @@ class Profile
function parent_profileid() { return $this->field('parent_profileid'); }
function parent_version() { return $this->field('parent_version'); }
function profile_nodelete() { return $this->field('profile_nodelete'); }
function portal_converted() { return $this->field('portal_converted'); }
# Private means only in the same project.
function IsPrivate() {
......
......@@ -122,6 +122,8 @@ $routing = array("myprofiles" =>
"Do_BindParameters",
"ConvertClassic" =>
"Do_ConvertClassic",
"ConvertRspec" =>
"Do_ConvertRspec",
"UpdateRepository" =>
"Do_UpdateRepository",
"GetRepository" =>
......
This diff is collapsed.
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