Commit ff3bebae authored by Leigh Stoller's avatar Leigh Stoller

New script to copy image from ops and mark it as released. Only for

global system images right now, exposing release and rollback to users to
going to take some thinking, since it will confuse people.
parent 545e32cf
#!/usr/bin/perl -w
#
# Copyright (c) 2014 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
use English;
use strict;
use Getopt::Std;
use Data::Dumper;
use File::stat;
use File::Basename;
#
# Release an image by changing the current version in the versions table
# to point to it. We first copy the image file over to boss, and after
# we call imagevalidate to make sure the DB is consistent.
#
sub usage()
{
print("Usage: imagerelease [-q] <imageid>\n" .
"Options:\n".
" -q Turn on quiet mode\n");
exit(-1);
}
my $optlist = "dq";
my $debug = 0;
my $quiet = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $FSNODE = "@FSNODE@";
my $PROJROOT = "@PROJROOT_DIR@";
my $IMAGEVALIDATE = "$TB/sbin/imagevalidate";
my $SCP = "/usr/bin/scp";
my $SUDO = "/usr/local/bin/sudo";
# Protos
sub fatal($);
#
# Untaint the path
#
$ENV{'PATH'} = "$TB/bin:$TB/sbin:/bin:/usr/bin:/usr/bin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use EmulabConstants;
use User;
use Image;
use OSinfo;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"q"})) {
$quiet = 1;
}
usage()
if (@ARGV != 1);
my $imageid = $ARGV[0];
my ($user,$user_uid);
if ($UID) {
$user = User->ThisUser();
if (!defined($user)) {
fatal("You ($UID) do not exist!");
}
$user_uid = $user->uid();
}
if ($UID && !$user->IsAdmin()) {
fatal("Only admins can release an image.");
}
my $image = Image->Lookup($imageid);
if (!defined($image)) {
$image = Image->LookupByName($imageid);
}
if (!defined($image)) {
fatal("No such image!");
}
if ($image->released()) {
fatal("Image is already released! ".
"Maybe you need to provide imageid:version");
}
if (!$image->ready()) {
fatal("Image is not ready yet!");
}
#
# Grab version 0 of the descriptor, which tells us if the image is really
# stored on boss. At some point, it would be nice to store unreleased
# versions of system images on boss too, but not enough disk space to
# support that, so we put newer versions in /proj until they are released,
# and then copy them over to avoid the NFS overhead when using the image.
# If we have to copy them back, we might also have to update the path in
# the database.
#
my $updatepath = 0;
my $copytofile = undef;
my $copyfromfile = undef;
my $version0;
#
# Before we do anything destructive, we lock the image.
#
if ($image->Lock()) {
fatal("Image is locked, please try again later!\n");
}
if ($image->version()) {
$version0 = Image->Lookup($image->imageid(), 0);
if (!defined($version0)) {
$image->Unlock();
fatal("Cannot lookup version zero of $image");
}
}
else {
$version0 = $image;
}
if ($version0->path() =~ /^\/usr\/testbed/) {
$copytofile = "/usr/testbed/images/" . basename($version0->path());
$copyfromfile = $image->path();
if ($image->version()) {
$updatepath = 1;
}
else {
#
# For version 0 of the image, create_image sticks the file out on /proj,
# but does not change the image path.
#
$copyfromfile = "$PROJROOT/" .
$image->pid() . "/images/" . basename($image->path());
}
}
if (defined($copytofile)) {
unlink($copytofile)
if (-e $copytofile);
if (!$quiet) {
print "Copying ${FSNODE}:$copyfromfile $copytofile\n";
}
system("$SUDO $SCP -p ${FSNODE}:$copyfromfile $copytofile");
if ($?) {
$image->Unlock();
fatal("Failed to scp ${FSNODE}:$copyfromfile $copytofile");
}
if ($updatepath) {
if ($image->Update({"path" => $copytofile})) {
$image->Unlock();
fatal("Failed to update path");
}
}
}
# Now mark as released.
if ($image->Release()) {
$image->Unlock();
fatal("Could not mark image as released!");
}
$image->Unlock();
exit(0);
sub fatal($)
{
my ($mesg) = @_;
print STDERR "*** $0:\n".
" $mesg\n";
exit(-1);
}
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