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

Image backed dataset versioning support; we now version image backed

datasets just like images, when versioning is enabled. Same syntax as
images (pid/imagename:version) in the NS file and rspec.
parent 34174779
......@@ -623,11 +623,14 @@ sub Create($$$$$$$$)
#
# Clone an image descriptor from the DB, bumping the version number
#
# XXX A lot of stuff in here gets skipped for datasets.
#
sub NewVersion($$$$)
{
my ($self, $creator, $baseimage, $usrerr_ref) = @_;
my $osid = $self->imageid();
my $version = $self->version();
my $isdataset = $self->isdataset();
my $tableid = int(rand(10000000));
my $typelist = "";
my $ostablename = "os_info_versions" . $tableid;
......@@ -642,42 +645,44 @@ sub NewVersion($$$$)
or return undef;
my $query_result =
DBQueryWarn("create temporary table $ostablename ".
"select * from os_info_versions ".
" where osid='$osid' and vers='$version'");
goto bad
if (!$query_result);
$query_result =
DBQueryWarn("create temporary table $imtablename ".
"select * from image_versions ".
"where imageid='$osid' and version='$version'");
goto bad
if (!$query_result);
#
# Grab the current type list.
#
$query_result =
DBQueryWarn("select distinct type from osidtoimageid ".
"where imageid='$osid'");
if (!$isdataset) {
$query_result =
DBQueryWarn("create temporary table $ostablename ".
"select * from os_info_versions ".
" where osid='$osid' and vers='$version'");
goto bad
if (!$query_result);
#
# Grab the current type list.
#
$query_result =
DBQueryWarn("select distinct type from osidtoimageid ".
"where imageid='$osid'");
goto bad
if (!$query_result);
goto bad
if (!$query_result);
my @types = ();
while (my ($type) = $query_result->fetchrow_array()) {
push(@types, $type);
}
$typelist = join(",", @types);
my @types = ();
while (my ($type) = $query_result->fetchrow_array()) {
push(@types, $type);
}
$typelist = join(",", @types);
#
# Update the type list in the image being cloned. Better to do this
# when the types are changed, but this works too since no one uses
# this until the image is deleted.
#
DBQueryWarn("update image_versions set nodetypes='$typelist' ".
"where imageid='$osid' and version='$version'");
#
# Update the type list in the image being cloned. Better to do this
# when the types are changed, but this works too since no one uses
# this until the image is deleted.
#
DBQueryWarn("update image_versions set nodetypes='$typelist' ".
"where imageid='$osid' and version='$version'");
}
#
# Now reset a few things in each table.
......@@ -692,19 +697,21 @@ sub NewVersion($$$$)
if (exists($ENV{'GENIURN'}) && $ENV{'GENIURN'} ne "") {
$updater_urn = ",updater_urn=". DBQuoteSpecial($ENV{'GENIURN'});
}
#
# Figure out which partition needs to be changed. EZ images only
# at this time.
#
my $part_vers = "";
for (my $i = 1; $i <= 4; $i++) {
my $func = "part${i}_osid";
if (defined($self->$func())) {
$part_vers = "part${i}_vers='${clone_vers}'";
last;
if (!$isdataset) {
for (my $i = 1; $i <= 4; $i++) {
my $func = "part${i}_osid";
if (defined($self->$func())) {
$part_vers = "part${i}_vers='${clone_vers}',";
last;
}
}
}
my $uid = $creator->uid();
my $uid_idx = $creator->uid_idx();
......@@ -747,19 +754,20 @@ sub NewVersion($$$$)
else {
$path .= ":${clone_vers}";
}
DBQueryWarn("update $ostablename set ".
" uuid=uuid(), ".
" vers='$clone_vers',".
" parent_osid=$parent_imageid,".
" parent_vers=$parent_version ".
"where osid='$osid'")
or goto bad;
if (!$isdataset) {
DBQueryWarn("update $ostablename set ".
" uuid=uuid(), ".
" vers='$clone_vers',".
" parent_osid=$parent_imageid,".
" parent_vers=$parent_version ".
"where osid='$osid'")
or goto bad;
}
DBQueryWarn("update $imtablename set ".
" uuid=uuid(),ready=0,path='$path',released=0, ".
" $part_vers, default_vers='$clone_vers', ".
" version='$clone_vers',".
" $part_vers default_vers='$clone_vers', ".
" version='$clone_vers',last_used=NULL, ".
" created=now(),nodetypes='$typelist', ".
" parent_imageid=$parent_imageid,".
" parent_version=$parent_version, ".
......@@ -771,12 +779,16 @@ sub NewVersion($$$$)
# And insert into the real table. At this point we will be
# inconsistent if we crash before the commit is done.
#
if (! (DBQueryWarn("insert into os_info_versions ".
"select * from $ostablename") &&
DBQueryWarn("insert into image_versions ".
"select * from $imtablename"))) {
if (!$isdataset) {
DBQueryWarn("insert into os_info_versions ".
"select * from $ostablename")
or goto bad;
}
if (! DBQueryWarn("insert into image_versions ".
"select * from $imtablename")) {
DBQueryWarn("delete from os_info_versions ".
"where osid='$osid' and vers='$clone_vers'");
"where osid='$osid' and vers='$clone_vers'")
if (!$isdataset);
DBQueryWarn("delete from image_versions ".
"where imageid='$osid' and version='$clone_vers'");
goto bad;
......@@ -1963,7 +1975,18 @@ sub MarkReleased($)
return 0;
}
# Last used, for datasets.
sub BumpLastUsed($)
{
my ($self) = @_;
my $imageid = $self->imageid();
my $version = $self->version();
return -1
if (! DBQueryWarn("update image_versions set last_used=now() ".
"where imageid='$imageid' and version='$version'"));
return 0;
}
# Are two images the same.
sub SameImage($$)
......
......@@ -2542,14 +2542,13 @@ sub CreateImage($)
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse();
}
#
# We do not version datasets yet,
#
my $opt = "";
if (defined($image) && $image->isdataset()) {
goto dataset;
$opt .= " -b $bsname ";
}
else {
$opt .= " -e" if ($wholedisk);
}
my $opt = "";
$opt .= " -e" if ($wholedisk);
#
# Let user override global setting.
......
......@@ -68,6 +68,7 @@ my $nodelta = 0; # To pass to create_image.
my $global = 0;
my $shared = 0;
my $bsname;
my ($base_osinfo, $base_image);
#
# Configure variables
......@@ -189,22 +190,39 @@ if (! (defined($project) && defined($group))) {
}
my $image = Image->Lookup($project->pid(), $imagename);
#
# Dataset checks.
#
if (defined($image)) {
if ($image->isdataset() && !defined($bsname)) {
fatal("You must provide a blockstore name (-b) for this image!");
}
}
elsif (defined($bsname)) {
fatal("Dataset must already exist before it can be cloned");
}
#
# Need to look up the base image; the image that is currently running
# on the node and being cloned.
#
my ($base_osinfo, $base_image) = $node->RunningOsImage();
# No support for cloning MFSs, so there will always be a base image.
if (! (defined($base_osinfo) && defined($base_image))) {
fatal("Could not determine osid/imageid for $node_id");
if ($image->isdataset()) {
$base_image = $image;
}
else {
($base_osinfo, $base_image) = $node->RunningOsImage();
# No support for cloning MFSs, so there will always be a base image.
if (! (defined($base_osinfo) && defined($base_image))) {
fatal("Could not determine osid/imageid for $node_id");
}
print "$node_id is running $base_osinfo,$base_image\n"
if ($debug);
}
print "$node_id is running $base_osinfo,$base_image\n"
if ($debug);
# See if enabled.
if ($DOPROVENANCE) {
$doprovenance =
EmulabFeatures->FeatureEnabled("ImageProvenance", $this_user, $project);
EmulabFeatures->FeatureEnabled("ImageProvenance", $this_user, $group);
# Temporary override for all geni projects until we can export deltas.
if ($project->IsNonLocal()) {
......@@ -222,11 +240,8 @@ if (defined($image)) {
#
# Only EZ images or Datasets via this interface.
#
if (!($image->ezid())) {
fatal("Only EZ images on this path. Dataset images not yet");
}
if ($image->isdataset() && !defined($bsname)) {
fatal("You must provide a blockstore name (-b) for this image!");
if (!($image->ezid() || $image->isdataset())) {
fatal("Only EZ images or datasets on this path.");
}
#
......@@ -254,7 +269,7 @@ if (defined($image)) {
$image = $image->LookupMostRecent();
if (!defined($image)) {
$image->Unlock();
fatal("Cannot lookup osinfo for $image");
fatal("Cannot lookup most recent version for $image");
}
#
......@@ -271,14 +286,19 @@ if (defined($image)) {
# We can reuse it, but reset the provenance just in case the node got
# reloaded.
#
# There is no provenance for datasets; strictly parent/child.
#
if (!$image->ready()) {
my $osinfo = OSinfo->Lookup($image->imageid(), $image->version());
if (!defined($osinfo)) {
$image->Unlock();
fatal("Cannot lookup osinfo for $image");
if (!$image->isdataset()) {
my $osinfo =
OSinfo->Lookup($image->imageid(), $image->version());
if (!defined($osinfo)) {
$image->Unlock();
fatal("Cannot lookup osinfo for $image");
}
$osinfo->SetProvenance($base_osinfo);
$image->SetProvenance($base_image);
}
$image->SetProvenance($base_image);
$osinfo->SetProvenance($base_osinfo);
$needclone = 0;
print "Reusing image version " . $image->version() . ", ".
"since it was never marked ready.\n";
......
......@@ -409,6 +409,7 @@ if (system("$checkquota -p $imagepid $user_uid") != 0) {
#
if ($WITHPROVENANCE) {
my $project = Project->Lookup($image->pid());
my $group = Group->Lookup($image->pid(), $image->gid());
if (!defined($project)) {
die("*** $0:\n".
" Could not lookup project for $image\n");
......@@ -416,7 +417,7 @@ if ($WITHPROVENANCE) {
# But allow feature override.
$doprovenance = EmulabFeatures->FeatureEnabled("ImageProvenance",
$this_user, $project);
$this_user, $group);
# Temporary override for all geni projects until we can export deltas.
if ($project->IsNonLocal()) {
......
......@@ -441,8 +441,8 @@ function Do_ModifyDataSet()
if ($embedded) {
$retval = SUEXEC($this_uid, $dataset->pid(),
"webcreate_image -b $safe_bsname -p $pid ".
"$dname $safe_nodeid",
"webclone_image -b $safe_bsname ".
"$pid/$dname $safe_nodeid",
SUEXEC_ACTION_IGNORE);
}
else {
......
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