Commit cf12fb1d authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

When triggering an update at another cluster, send along the urn of the

user doing the image snapshot. At the image origin cluster, use this URN
to set the updater urn for the new image version, and if that urn is fot
a real local user, also set the updater,updater_idx accordingly. Lastly,
the image import *must* be done in the context of a user in the project
of the image, so fall back to using the image creator.
parent 90448a24
......@@ -3470,12 +3470,17 @@ sub TriggerImageUpdate($)
print STDERR Dumper($blob);
# Must have all these:
foreach my $key ("origin_uuid", "imagename", "metadata_url") {
foreach my $key ("origin_uuid", "imagename", "metadata_url",
"updater_urn") {
if (! (exists($blob->{$key}) &&
defined($blob->{$key}) && $blob->{$key} ne "")) {
return GeniResponse->MalformedArgsResponse("Missing $key");
}
}
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"invalid updater urn")
if (! GeniHRN::IsValid($blob->{'updater_urn'}));
my $localimage = Image->Lookup($blob->{'origin_uuid'});
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED)
if (!defined($localimage));
......@@ -3522,9 +3527,26 @@ sub TriggerImageUpdate($)
"Conflicting image update is pending");
}
my $safe_url = DBQuoteSpecial($blob->{'metadata_url'});
my $safe_urn = DBQuoteSpecial($blob->{'updater_urn'});
my $update_fields = "";
#
# We might know the updater or we might not. If we do that is nice,
# cause then we can set the updater fields in the new image version
# accordingly. If not a local user record, then at least we can set
# updater URN, but do the actual import update in the context of the
# image creator (image_import decides this).
#
my $update_user = GeniUser->Lookup($blob->{'updater_urn'}, 1);
if (defined($update_user)) {
my $updater = $update_user->uid();
my $updater_idx = $update_user->uid_idx();
$update_fields = ", updater='$updater',updater_idx='$updater_idx'";
}
emdb::DBQueryWarn("insert into image_updates set ".
" imageid='$imageid',url=$safe_url");
" imageid='$imageid',url=$safe_url, ".
" updater_urn=$safe_urn $update_fields");
$localimage->Unlock();
#
......@@ -3536,7 +3558,7 @@ sub TriggerImageUpdate($)
if ($mypid) {
return GeniResponse->Create(GENIRESPONSE_SUCCESS)
}
# Try to import right away, if it fails the daemon will catch it later.
system("$IMPORTER -d -g -r -c $imageid");
return 0;
......
......@@ -230,8 +230,16 @@ sub MapToLocalImage($$)
"Not allowed to import system image: $urn");
}
# Try to import the descriptor.
system("$IMPORTER -d -p GeniSlices $safe_url");
#
# Try to import the descriptor. Since we are putting the image into
# the GeniSlices project, we must execute as the GeniUser. But
# when PROTOGENI_LOCALUSER=1, we might be running as the user
# creating the slice. All imported images are globally available,
# so makes no sense to put them into the project of the slice,
# and in fact, if someone else uses the image, the update check
# will fail unless we do it as the geniuser.
#
GeniUtil::ExecuteAsGeniUser("$IMPORTER -d -p GeniSlices $safe_url");
if ($?) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Image importer failure for $urn");
......@@ -323,6 +331,7 @@ sub TriggerUpdate($$)
my $blob = {
"origin_uuid" => $origin_uuid,
"imagename" => $image->versname(),
"updater_urn" => $image->updater_urn(),
"metadata_url" => $image->LocalVersionURL(),
};
......
......@@ -62,6 +62,7 @@ my $user;
my $group;
my $image;
my $imagename;
my $copyback_urn;
#
# Configure variables
......@@ -206,7 +207,6 @@ if (!defined($user)) {
fatal("You ($UID) do not exist!");
}
}
my $user_uid = $user->uid();
if ($update) {
usage()
......@@ -217,6 +217,8 @@ if ($update) {
fatal("Image descriptor does not exist");
}
if ($copyback) {
my ($updater_uid,$updater_idx);
#
# We have to look in the updates table, but we want to do this
# locked so that no one else can mess with it. So lock up here,
......@@ -229,7 +231,7 @@ if ($update) {
}
my $imageid = $image->imageid();
my $query_result =
DBQueryWarn("select url from image_updates ".
DBQueryWarn("select * from image_updates ".
"where imageid='$imageid'");
if (!$query_result) {
$image->Unlock();
......@@ -240,7 +242,31 @@ if ($update) {
$image->Unlock();
exit(0);
}
($url) = $query_result->fetchrow_array();
my $row = $query_result->fetchrow_hashref();
$url = $row->{'url'};
$updater_uid = $row->{'updater'};
$updater_idx = $row->{'updater_idx'};
$copyback_urn = $row->{'updater_urn'};
#
# Also want the user doing the import to be the user who actually
# did the update on the remote cluster, if we happen to have that
# record. If not, we have to do it as the creator (someone in the
# project the image belongs to).
#
$user = undef;
if (defined($updater_uid)) {
$user = User->Lookup($updater_idx);
}
if (!defined($user)) {
$user = User->Lookup($image->creator_idx());
}
if (!defined($user)) {
print STDERR "No current user to import image as.\n";
$image->Unlock();
exit(-1);
}
$UID = $SAVEUID = $user->unix_uid();
}
else {
if (!defined($image->metadata_url())) {
......@@ -466,6 +492,10 @@ if ($getimage) {
# Clear this to make the image gets posted.
$image->ClearIMSReported();
# Mark the updater.
$image->Update({'updater_urn' => $copyback_urn})
if (defined($copyback_urn));
# Tell the IMS about this new image. If this fails, the daemon
# will take care of it.
system("$POSTIMAGEINFO -d $imageid");
......@@ -713,6 +743,7 @@ sub FetchImageFile($$)
{
my ($url, $localfile) = @_;
my $safe_url = User::escapeshellarg($url);
my $user_uid = $user->uid();
#
# Build up a new command line to do the fetch on ops
......
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