Commit 0c653722 authored by Leigh B Stoller's avatar Leigh B Stoller

Change how all geni images are imported by url; always import as geniuser

and always import into the GeniSlices project. Previously, images were
being imported into the project of the slice experiment, by the geniuser.

When PROTOGENI_LOCALUSER is turned off, this change does not affect
anything, since it is still geniuser doing the import, and all imported
images are consider global and thus cross-project usable. So where we stick
the image is not really important, but putting all geni imported images in
one place is more convenient (sure makes it easier to find them). But more
important, this change is backwards compatible with existing imports. 

Later, if the source image is updated, and a new user (in another project)
uses that image, the update (pulling the updated image scross) is done by
geniuser (who is the leader of all geni holding projects), who has write
access to the image whatever project it is in. 

What about when PROTOGENI_LOCALUSER is turned on? There are actually two
sub cases here.

1. The user is using an aggregate in a different domain then their SA. Say,
   when a Cloudlab Portal user is creating an experiment at the Clemson
   cluster (which has PROTOGENI_LOCALUSER=1). In this case, clemson does
   not know anything about the user anyway, and so its pretty much like the
   case described above since everything is done by the geniuser in holding
   projects owned by the geniuser.

2. The user is using the same aggregate as their SA. Say, when a Cloudlab
   Portal user is creating an experiment at the Emulab cluster. In this
   case Emulab knows the user and project, and everything is done as that
   user in the actual project (there is no geni holding project).

   If we import the image into that project as the actual user, we are okay
   at first; as above, all images are global and cross-project, so anyone
   can use it. But what if the source image changes and then a different
   user in a different project tries to use it? The backend is going to try
   to import the new version, but that fails cause the current user does
   not have write access to the image.

   Hence the real reason for this change; if always import into GeniSlices
   as geniuser, we do not get into this permission problem.
parent ae6fb72e
......@@ -1016,9 +1016,18 @@ sub Action($$$;$)
#
# Download the images. If this fails, we have wasted our time,
# but we want to do this after we have forked off from the parent
# and we have returned to the client (rpc).
# and we have returned to the client (rpc).
#
my $output = GeniUtil::ExecQuiet("$IMAGE_SETUP -d -g $pid,$eid");
# All imported images are globally available, so makes no sense to
# put them into the project of the slice. In fact, if someone else
# in another project tried to use the same image, the update will
# fail when PROTOGENI_LOCALUSER=1 since it was imported by another
# real user, and the current user will not have write permission
# on it.
#
my $output =
GeniUtil::ExecuteQuietAsGeniUser("$IMAGE_SETUP ".
"-d -g -p GeniSlices $pid,$eid");
if ($?) {
$msg = "Could not setup images:\n$output";
goto bad;
......
......@@ -2407,9 +2407,16 @@ sub GetTicketAuxAux($$$$$$$$$$$)
#
# This creates the descriptors but does not download the images.
# Must be done before the mapper runs.
#
my $output = GeniUtil::ExecQuiet("$IMAGE_SETUP $pid,$eid");
# Must be done before the mapper runs. All imported images are
# globally available, so makes no sense to put them into the
# project of the slice. In fact, if someone else in another project
# tried to use the same image, the update will fail when
# PROTOGENI_LOCALUSER=1 since it was imported by another real user,
# and the current user will not have write permission on it.
#
my $output =
GeniUtil::ExecuteQuietAsGeniUser("$IMAGE_SETUP ".
"-p GeniSlices $pid,$eid");
if ($?) {
my $message = "Could not setup images:\n$output";
$response = GeniResponse->Create(GENIRESPONSE_ERROR, undef, $message);
......@@ -3122,6 +3129,12 @@ sub GetTicketAuxAux($$$$$$$$$$$)
VLan::ClearReservedVlanTag($lanid, $vlan_tag);
}
if ($v2 && $level == 0) {
if (defined($slice_experiment) && -e $slice_experiment->WorkDir()) {
my $dir = $slice_experiment->WorkDir();
system("/bin/rm -rf ${dir}.failed");
system("/bin/cp -rp ${dir} ${dir}.failed");
}
CleanupDeadSlice($slice, 1)
if (defined($slice));
return $response;
......
......@@ -263,19 +263,23 @@ sub Create($$$$;$$)
# If the existing entry is a placeholder, and we got the creator,
# then replace the existing entry to make it a non-placeholder.
#
if ($isplaceholder && defined($creator)) {
push(@insert_data, "idx='$curidx'");
if ($isplaceholder) {
if (defined($creator)) {
push(@insert_data, "idx='$curidx'");
if (! DBQueryWarn("replace into geni_slices set " .
" isplaceholder=0, ".
join(",", @insert_data))) {
DBQueryWarn("unlock tables");
return undef;
if (! DBQueryWarn("replace into geni_slices set " .
" isplaceholder=0, ".
join(",", @insert_data))) {
DBQueryWarn("unlock tables");
return undef;
}
$idx = $curidx;
}
$idx = $curidx;
goto lookup;
}
# Slice exists, no inserts needed. Just lookup.
goto lookup;
print STDERR "Slice already exists in database\n";
DBQueryWarn("unlock tables");
return undef;
}
# Do this after above code since we might need to overwrite entry.
push(@insert_data, "idx='$idx'");
......
......@@ -115,6 +115,7 @@ sub FlipToUser($$;$)
$EGID = $glist;
$EUID = $UID = $unix_uid;
$ENV{'USER'} = $user;
$ENV{'GID'} = $default_gid;
$ENV{'LOGNAME'} = $user;
$ENV{'HOME'} = "$USERROOT/$user";
return 0;
......@@ -133,6 +134,51 @@ sub FlipToElabMan()
return FlipToUser($PROTOUSER, $PROTOPROJ);
}
#
# Execute a command as GeniUser and then return to original UID/GID
#
sub ExecuteAsGeniUser($;$)
{
my ($command, $default_gid) = @_;
my $current_uid = $UID;
my $current_euid = $EUID;
my $current_gid = $GID;
my $current_egid = $EGID;
FlipToGeniUser($default_gid);
my $retval = system($command);
$EUID = 0;
$GID = $current_gid;
$EGID = $current_egid;
$UID = $current_uid;
$EUID = $current_euid;
return $retval;
}
sub ExecuteQuietAsGeniUser($;$)
{
my ($command, $default_gid) = @_;
my $current_uid = $UID;
my $current_euid = $EUID;
my $current_gid = $GID;
my $current_egid = $EGID;
FlipToGeniUser($default_gid);
my $output = ExecQuiet($command);
$EUID = 0;
$GID = $current_gid;
$EGID = $current_egid;
$UID = $current_uid;
$EUID = $current_euid;
return $output;
}
#
# Store up the list of caches to flush
#
......
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