Commit 3e6ea574 authored by Leigh B Stoller's avatar Leigh B Stoller

Fix (finish?) profile provenance recording. I guess this was something I had

intended to finish, but never did. Unfortunate since we have lost some info
that might have been useful.

In addition, we now record provenance on a plain profile copy, in addition
to a clone.

Fixes to the profile history display, and add a new pointer to the profile
derived from when it is not null.
parent f5cc7006
......@@ -406,7 +406,7 @@ sub NewVersion($$)
" parent_profileid,parent_version,rspec, ".
" script,paramdefs) ".
"select name,profileid,'$newvers',pid,pid_idx, ".
" '$uid','$uid_idx',now(),uuid(),parent_profileid, ".
" '$uid','$uid_idx',now(),uuid(),'$profileid', ".
" '$version',rspec,script,paramdefs ".
"from apt_profile_versions as v ".
"where v.profileid='$profileid' and ".
......@@ -517,8 +517,7 @@ sub Delete($$)
}
else {
# Set deleted on all of the versions.
DBQueryWarn("update apt_profile_versions set ".
" deleted=now(),locked=null,locker_pid=0 ".
DBQueryWarn("update apt_profile_versions set deleted=now() ".
"where profileid='$profileid'")
or goto bad;
# Delete any leftover webtasks.
......@@ -557,19 +556,18 @@ sub DeleteVersion($)
my $version = $self->version();
#
# Only the "head" version can be deleted
# Need to know what profile becomes the head version. This will
# always be the highest numbered undeleted profile.
#
my $query_result =
DBQueryWarn("select max(version) from apt_profile_versions ".
"where profileid='$profileid'");
"where profileid='$profileid' and version!=${version} ".
" and deleted is null");
goto bad
if (!$query_result || !$query_result->numrows);
my ($head) = $query_result->fetchrow_array();
if ($head != $version) {
print STDERR "Profile::DeleteVersion: not the head version of $self\n";
goto bad;
}
my ($newhead) = $query_result->fetchrow_array();
# Delete leftover webtask.
DBQueryWarn("delete web_tasks from apt_profile_versions ".
"left join web_tasks on ".
......@@ -578,12 +576,12 @@ sub DeleteVersion($)
" apt_profile_versions.version='$version'");
goto bad
if (!DBQueryWarn("delete from apt_profile_versions ".
if (!DBQueryWarn("update apt_profile_versions set deleted=now() ".
"where profileid='$profileid' and ".
" version='$version'"));
goto bad
if (!DBQueryWarn("update apt_profiles set version=version-1 ".
if (!DBQueryWarn("update apt_profiles set version=$newhead ".
"where profileid='$profileid' and ".
" version='$version'"));
DBQueryWarn("unlock tables");
......@@ -1158,7 +1156,7 @@ sub IsHead($)
my $query_result =
DBQueryWarn("select max(version) from apt_profile_versions ".
"where profileid='$profileid'");
"where profileid='$profileid' and deleted is null");
return -1
if (!$query_result || !$query_result->numrows);
......
......@@ -36,20 +36,23 @@ use POSIX qw(setsid);
#
sub usage()
{
print("Usage: manage_profile create [-s uuid] <xmlfile>\n");
print("Usage: manage_profile create [-s uuid | -c uuid] <xmlfile>\n");
print("Usage: manage_profile update <profile> <xmlfile>\n");
print("Usage: manage_profile publish <profile>\n");
print("Usage: manage_profile delete <profile>\n");
exit(-1);
}
my $optlist = "ds:t:";
my $optlist = "ds:t:c:";
my $debug = 0;
my $update = 0;
my $snap = 0;
my $copy = 0;
my $copyuuid;
my $uuid;
my $rspec;
my $script;
my $profile;
my $parent_profile;
my $instance;
my $aggregate;
my $node_id;
......@@ -128,7 +131,11 @@ if (defined($options{"d"})) {
}
if (defined($options{"s"})) {
$snap = 1;
$uuid = $options{"s"};
$copyuuid = $options{"s"};
}
if (defined($options{"c"})) {
$copy = 1;
$copyuuid = $options{"c"};
}
if (defined($options{"t"})) {
$webtask_id = $options{"t"};
......@@ -345,9 +352,9 @@ if (defined($script) && $script ne "") {
# sanity check to make sure there is just one node.
#
if ($snap) {
$instance = APT_Instance->Lookup($uuid);
$instance = APT_Instance->Lookup($copyuuid);
if (!defined($instance)) {
fatal("Could not look up instance $uuid");
fatal("Could not look up instance $copyuuid");
}
if ($instance->status() ne "ready") {
$errors{"error"} = "Instance must be in the ready state for cloning";
......@@ -375,7 +382,15 @@ if ($snap) {
$errors{"error"} = "$node_id is not at " . $aggregate->aggregate_urn();
UserError();
}
$parent_profile = $instance->Profile();
}
elsif ($copy) {
$parent_profile = APT_Profile->Lookup($copyuuid);
if (!defined($parent_profile)) {
fatal("Could not look up copy profile $copyuuid");
}
}
if ($update) {
$profile = APT_Profile->Lookup($uuid);
if (!defined($profile)) {
......@@ -440,14 +455,12 @@ if ($update) {
else {
my $usererror;
$profile = APT_Profile->Lookup($new_args{"pid"}, $new_args{"name"});
if (defined($profile)) {
if (defined(APT_Profile->Lookup($new_args{"pid"}, $new_args{"name"}))) {
$errors{"profile_name"} = "Already in use";
UserError();
}
$profile =
APT_Profile->Create($profile, $project,
$this_user, \%new_args, \$usererror);
$profile = APT_Profile->Create($parent_profile, $project,
$this_user, \%new_args, \$usererror);
if (!defined($profile)) {
if (defined($usererror)) {
$errors{"profile_name"} = $usererror;
......@@ -683,11 +696,8 @@ sub DeleteProfile($)
fatal("Could not delete profile version");
}
else {
# Purge it. At some point we want to save them.
$profile->Delete(1) == 0 or
$profile->Delete(0) == 0 or
fatal("Could not delete profile");
# Kill off object webtask, since we do not do that when purging.
WebTask->DeleteByObject($profile->uuid());
}
# No need for this anonymous webtask anymore.
$webtask->Delete()
......@@ -750,8 +760,6 @@ sub CanDelete($)
my $project = Project->Lookup($profile->pid_idx());
return 0
if (!defined($project));
return 0
if (!$profile->IsHead());
return 1
if ($this_user->IsAdmin() || $this_user->stud());
return 1
......
......@@ -247,7 +247,7 @@ CREATE TABLE `apt_instances` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `apt_profile_versions`
-- Table structure for table `apt_profile_favorites`
--
DROP TABLE IF EXISTS `apt_profile_favorites`;
......@@ -284,7 +284,6 @@ CREATE TABLE `apt_profile_versions` (
`script` mediumtext,
`paramdefs` mediumtext,
PRIMARY KEY (`profileid`,`version`),
UNIQUE KEY `pidname` (`pid_idx`,`name`,`version`),
UNIQUE KEY `uuid` (`uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (DBKeyExists("apt_profile_versions", "pidname")) {
DBQueryFatal("alter table apt_profile_versions drop key `pidname`");
}
return 0;
}
# Local Variables:
# mode:perl
# End:
......@@ -132,7 +132,7 @@ if (isset($profile)) {
SPITUSERERROR("Illegal profile for guest user: $profile");
exit();
}
if (! $obj) {
if (! $obj || $obj->deleted()) {
SPITUSERERROR("No such profile: $profile");
exit();
}
......
......@@ -108,6 +108,7 @@ function (_, sup, filesize, JacksEditor, ShowImagingModal, moment, ppstart,
history: window.HISTORY,
activity: window.ACTIVITY,
manual: window.MANUAL,
copyuuid: (window.COPYUUID || null),
snapuuid: (window.SNAPUUID || null),
general_error: (errors.error || ''),
iscloud: window.ISCLOUD,
......
......@@ -47,6 +47,7 @@ $this_idx = $this_user->uid_idx();
$optargs = OptionalPageArguments("create", PAGEARG_STRING,
"action", PAGEARG_STRING,
"uuid", PAGEARG_STRING,
"copyuuid", PAGEARG_STRING,
"snapuuid", PAGEARG_STRING,
"finished", PAGEARG_BOOLEAN,
"formfields", PAGEARG_ARRAY);
......@@ -57,7 +58,7 @@ $optargs = OptionalPageArguments("create", PAGEARG_STRING,
function SPITFORM($formfields, $errors)
{
global $this_user, $projlist, $action, $profile, $DEFAULT_AGGREGATE;
global $notifyupdate, $notifyclone, $snapuuid, $am_array, $ISCLOUD;
global $notifyupdate, $notifyclone, $copyuuid, $snapuuid, $am_array, $ISCLOUD;
global $version_array, $WITHPUBLISHING;
$viewing = 0;
$candelete = 0;
......@@ -194,11 +195,14 @@ function SPITFORM($formfields, $errors)
echo " window.ISPPPROFILE = $ispp;\n";
echo " window.WITHPUBLISHING = $WITHPUBLISHING;\n";
if ($ISCLOUD) {
echo " window.ISCLOUD = true;";
echo " window.ISCLOUD = true;\n";
} else {
echo " window.ISCLOUD = false;";
echo " window.ISCLOUD = false;\n";
}
if (isset($snapuuid)) {
if (isset($copyuuid)) {
echo " window.COPYUUID = '$copyuuid';\n";
}
elseif (isset($snapuuid)) {
echo " window.SNAPUUID = '$snapuuid';\n";
}
echo "</script>\n";
......@@ -231,6 +235,9 @@ if (isset($action) && ($action == "edit" || $action == "copy")) {
else if ($profile->locked()) {
SPITUSERERROR("Profile is currently locked!");
}
else if ($profile->deleted()) {
SPITUSERERROR("Profile is has been deleted!");
}
if ($action == "edit") {
if ($this_idx != $profile->creator_idx() && !ISADMIN()) {
SPITUSERERROR("Not enough permission!");
......@@ -246,13 +253,20 @@ if (isset($action) && ($action == "edit" || $action == "copy")) {
$profileid = $profile->profileid();
$query_result =
DBQueryFatal("select v.*,DATE(v.created) as created ".
DBQueryFatal("select v.*,DATE(v.created) as created, ".
" vp.uuid as parent_uuid ".
" from apt_profile_versions as v ".
"where v.profileid='$profileid' ".
"left join apt_profile_versions as vp on ".
" v.parent_profileid is not null and ".
" vp.profileid=v.parent_profileid and ".
" vp.version=v.parent_version ".
"where v.profileid='$profileid' and ".
" v.deleted is null ".
"order by v.created desc");
while ($row = mysql_fetch_array($query_result)) {
$uuid = $row["uuid"];
$puuid = $row["parent_uuid"];
$version = $row["version"];
$pversion= $row["parent_version"];
$created = $row["created"];
......@@ -261,9 +275,6 @@ if (isset($action) && ($action == "edit" || $action == "copy")) {
$desc = '';
$obj = array();
if ($version == 0) {
$pversion = " ";
}
if (!$published) {
$published = " ";
}
......@@ -281,6 +292,7 @@ if (isset($action) && ($action == "edit" || $action == "copy")) {
$obj["description"] = $desc;
$obj["created"] = $created;
$obj["published"] = $published;
$obj["parent_uuid"] = $puuid;
$obj["parent_version"] = $pversion;
$version_array[] = $obj;
......@@ -331,6 +343,10 @@ if (! isset($create)) {
SPITUSERERROR("Not allowed to access this profile!");
}
}
elseif ($action == "copy") {
# Pass this along through the new create page.
$copyuuid = $profile->uuid();
}
$defaults["profile_rspec"] = $profile->rspec();
$defaults["profile_who"] = "private";
if ($profile->script() && $profile->script() != "") {
......@@ -471,7 +487,7 @@ else {
}
#
# Sanity check the snapuuid argument.
# Sanity check the snapuuid argument when doing a clone.
#
if (isset($action) && $action == "clone") {
if (!isset($snapuuid) || $snapuuid == "" || !IsValidUUID($snapuuid)) {
......@@ -598,8 +614,11 @@ if ($action == "edit") {
}
else {
$command .= " create -t $webtask_id ";
if (isset($snapuuid)) {
$command .= " -s " . escapeshellarg($snapuuid);
if (isset($copyuuid)) {
$command .= "-c " . escapeshellarg($copyuuid);
}
elseif (isset($snapuuid)) {
$command .= "-s " . escapeshellarg($snapuuid);
}
}
$command .= " $xmlname";
......@@ -626,6 +645,7 @@ if ($retval) {
}
}
}
$webtask->Delete();
}
unlink($xmlname);
if (count($errors)) {
......
......@@ -52,14 +52,20 @@ $profileid = $profile->profileid();
$profiles = array();
$query_result =
DBQueryFatal("select v.*,DATE(v.created) as created ".
DBQueryFatal("select v.*,DATE(v.created) as created,vp.uuid as parent_uuid ".
" from apt_profile_versions as v ".
"where v.profileid='$profileid' ".
"left join apt_profile_versions as vp on ".
" v.parent_profileid is not null and ".
" vp.profileid=v.parent_profileid and ".
" vp.version=v.parent_version ".
"where v.profileid='$profileid' and v.deleted is null ".
"order by v.created desc");
while ($row = mysql_fetch_array($query_result)) {
$idx = $row["profileid"];
$pidx = $row["parent_profileid"];
$uuid = $row["uuid"];
$puuid = $row["parent_uuid"];
$version = $row["version"];
$pversion= $row["parent_version"];
$name = $row["name"];
......@@ -70,9 +76,6 @@ while ($row = mysql_fetch_array($query_result)) {
$rspec = $row["rspec"];
$desc = '';
if ($version == 0) {
$pversion = " ";
}
if (!$published) {
$published = " ";
}
......@@ -89,6 +92,7 @@ while ($row = mysql_fetch_array($query_result)) {
$profile["description"] = $desc;
$profile["created"] = $created;
$profile["published"] = $published;
$profile["parent_uuid"] = $puuid;
$profile["parent_version"] = $pversion;
$profiles[] = $profile;
......
......@@ -285,7 +285,7 @@ class Profile
$query_result =
DBQueryWarn("select max(version) from apt_profile_versions ".
"where profileid='$profileid'");
"where profileid='$profileid' and deleted is null");
if (!$query_result || !mysql_num_rows($query_result)) {
return -1;
}
......
......@@ -120,6 +120,9 @@
role="alert"><center>Update Successful!</center></div>
<!-- Hidden variables -->
<input type='hidden' name='action' value='<%= action %>'>
<% if (copyuuid) { %>
<input type='hidden' name='copyuuid' value='<%= copyuuid %>'>
<% } %>
<% if (snapuuid) { %>
<input type='hidden' name='snapuuid' value='<%= snapuuid %>'>
<% } %>
......@@ -627,8 +630,17 @@
<td><%- profile.published %></td>
<% } %>
<td style='text-align:center'>
<a href='manage_profile.php?action=edit&uuid=<%- profile.uuid %>'>
<%- profile.parent_version %></a>
<% if (profile.parent_uuid) { %>
<% if (profile.version == 0) { %>
<a href='show-profile.php?uuid=<%- profile.parent_uuid %>'>
<%- profile.parent_version %></a>
<% } else { %>
<a href='manage_profile.php?action=edit&uuid=<%- profile.parent_uuid %>'>
<%- profile.parent_version %></a>
<% } %>
<% } else { %>
&nbsp;
<% } %>
</td>
</tr>
<% }); %>
......
......@@ -30,8 +30,17 @@
<td><%- profile.published %></td>
<% } %>
<td style='text-align:center'>
<a href='manage_profile.php?action=edit&uuid=<%- profile.uuid %>'>
<%- profile.parent_version %></a>
<% if (profile.parent_uuid) { %>
<% if (profile.version == 0) { %>
<a href='show-profile.php?uuid=<%- profile.parent_uuid %>'>
<%- profile.parent_version %></a>
<% } else { %>
<a href='manage_profile.php?action=edit&uuid=<%- profile.parent_uuid %>'>
<%- profile.parent_version %></a>
<% } %>
<% } else { %>
&nbsp;
<% } %>
</td>
</tr>
<% }); %>
......
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