Commit 080727f8 authored by Leigh Stoller's avatar Leigh Stoller

Allow export of indvidual runs.

Also remove guid/version argument requirement for template_export.
parent abbf9ade
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# Copyright (c) 2006, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -28,23 +28,21 @@ use Data::Dumper;
sub usage()
{
print(STDERR
"Usage: template_export [-q] [-s] -i <exptidx> <guid/vers>\n".
"Usage: template_export [-q] [-s] [-r <runidx>] -i <idx>\n".
"switches and arguments:\n".
"-q - be less chatty\n".
"-s - spew to stdout (as for web page).\n".
"-i <exptidx> - Instance index to export\n".
"<guid/vers> - GUID and version to swapin\n");
"-i <idx> - Instance index to export\n".
"-r <runidx> - Run index to export\n");
exit(-1);
}
my $optlist = "qi:ds";
my $optlist = "qi:dsr:";
my %options = ();
my $spew = 0;
my $quiet = 0;
my $debug = 0;
my $eid;
my $exptidx;
my $guid;
my $version;
my $runidx;
my %bindings;
#
......@@ -61,9 +59,11 @@ my $checkquota = "$TB/sbin/checkquota";
my $TAR = "/usr/bin/tar";
# Locals
my $dbuid;
my $template;
my $instance;
my $pid;
my $guid;
my $version;
my $archive_tag;
# Protos
......@@ -79,6 +79,7 @@ use libdb;
use libtestbed;
use libtblog;
use Template;
use User;
# Be careful not to exit on transient error
$libdb::DBQUERY_MAXTRIES = 0;
......@@ -108,8 +109,9 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Verify user and get his DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
tbdie("You do not exist in the Emulab Database!");
my $this_user = User->ThisUser();
if (! defined($this_user)) {
tbdie("You ($UID) do not exist!");
}
# Now parse arguments.
......@@ -119,31 +121,29 @@ ParseArgs();
libArchive::setdebug($debug);
#
# Grab template info and do access check.
# Grab instance info and do access check via the template.
#
$template = Template->Lookup($guid, $version);
if (!defined($template)) {
tbdie("Experiment template $guid/$version does not exist!");
$instance = Template::Instance->LookupByExptidx($exptidx);
if (!defined($instance)) {
fatal(-1, "Could not get instance record for experiment $exptidx!");
}
if (! TBProjAccessCheck($dbuid,
$template = $instance->template();
$pid = $template->pid();
$guid = $template->guid();
$version = $template->vers();
if (! TBProjAccessCheck($this_user->uid(),
$template->pid(), $template->gid(),
TB_PROJECT_READINFO)) {
tberror("You do not have permission to export template $guid/$version");
exit(1);
}
my $pid = $template->pid();
$instance = Template::Instance->LookupByExptidx($exptidx);
if (!defined($instance)) {
fatal(-1, "Could not get instance record for experiment $exptidx!");
}
if ($instance->ArchiveTag(\$archive_tag) < 0) {
fatal(-1, "Could not get current archive tag for instance $exptidx!");
}
if (system("$checkquota $dbuid") != 0) {
if (system("$checkquota " . $this_user->uid()) != 0) {
tberror("You are over your disk quota on $CONTROL; ".
"please login there and cleanup!");
exit(1);
......@@ -253,8 +253,12 @@ if (keys(%runlist)) {
$root->{"runs"} = {};
foreach my $name (keys(%runlist)) {
my $rowref = $runlist{$name};
my $runidx = $rowref->{"idx"};
my $dir = "$checkout/run${runidx}";
# Export only requested run.
next
if (defined($runidx) && $runidx != $rowref->{"idx"});
my $dir = "$checkout/run" . $rowref->{"idx"};
my $tag = $rowref->{"ending_archive_tag"};
# This could happen if template still instantiated (last run).
......@@ -303,23 +307,9 @@ sub ParseArgs()
usage();
}
if (@ARGV != 1) {
usage();
}
usage()
if (@ARGV);
#
# Pick up guid/version first and untaint.
#
my $tmp = shift(@ARGV);
if ($tmp =~ /^([\w]*)\/([\d]*)$/) {
$guid = $1;
$version = $2;
}
else {
tbdie("Bad data in argument: $tmp");
}
if (defined($options{"i"})) {
$exptidx = $options{"i"};
......@@ -328,7 +318,7 @@ sub ParseArgs()
tbdie("Improper experiment index!");
}
# real check.
if ($exptidx =~ /^([\w]*)$/) {
if ($exptidx =~ /^([\d]*)$/) {
$exptidx = $1;
}
else {
......@@ -339,6 +329,22 @@ sub ParseArgs()
tbdie("You must supply the -i option!");
}
if (defined($options{"r"})) {
$runidx = $options{"r"};
if (! TBcheck_dbslot($runidx, "default", "int",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper run index!");
}
# real check.
if ($runidx =~ /^([\d]*)$/) {
$runidx = $1;
}
else {
tbdie("Bad data in argument: $runidx");
}
}
if (defined($options{"q"})) {
$quiet = 1;
}
......
......@@ -20,6 +20,7 @@ $isadmin = ISADMIN();
$reqargs = RequiredPageArguments("instance", PAGEARG_INSTANCE);
$optargs = OptionalPageArguments("canceled", PAGEARG_BOOLEAN,
"confirmed", PAGEARG_BOOLEAN,
"runidx", PAGEARG_INTEGER,
"spew", PAGEARG_BOOLEAN);
$template = $instance->GetTemplate();
......@@ -40,17 +41,27 @@ if (! $template->AccessCheck($this_user, $TB_EXPT_MODIFY)) {
USERERROR("You do not have permission to export in template ".
"$guid/$vers!", 1);
}
if (isset($runidx) && !$instance->ValidRun($runidx)) {
USERERROR("Run '$runidx' is not a valid run in instance '$exptidx'", 1);
}
if (!isset($confirmed)) {
PAGEHEADER("Template Export");
echo $template->PageHeader();
echo "<br><br>\n";
echo "<center><br><font size=+1>
Export instance $exptidx in Template
in Template $guid/$vers?</font>\n";
Export instance $exptidx " .
(isset($runidx) ? "(Run $runidx)" : "") . "?";
echo "</font>";
$template->Show();
$url = CreateURL("template_export", $instance);
if (isset($runidx)) {
$url .= "&runidx=$runidx";
}
echo "<form action='$url' method=post>\n";
echo "<br>\n";
......@@ -124,13 +135,18 @@ function SPEWCLEANUP()
#
# Run the backend script.
#
$optarg = (isset($runidx) ? "-r " . escapeshellarg($runidx) : "");
if ($spew) {
ignore_user_abort(1);
register_shutdown_function("SPEWCLEANUP");
if ($fp = popen("$TBSUEXEC_PATH $uid $pid,$unix_gid ".
" webtemplate_export -s -i $exptidx $guid/$vers",
"r")) {
TBERROR("$TBSUEXEC_PATH $uid $pid,$unix_gid ".
" webtemplate_export -s $optarg -i $exptidx", 0);
if (($fp = popen("$TBSUEXEC_PATH $uid $pid,$unix_gid ".
" webtemplate_export -s -i $exptidx",
"r"))) {
header("Content-Type: application/x-tar");
header("Content-Encoding: x-gzip");
header("Content-Disposition: attachment; filename=$exptidx.tgz");
......@@ -157,8 +173,7 @@ if ($spew) {
# Standard mode ...
#
$retval = SUEXEC($uid, "$pid,$unix_gid",
"webtemplate_export " . ($spew ? "-s" : "") .
"-i $exptidx $guid/$vers",
"webtemplate_export $optarg -i $exptidx",
SUEXEC_ACTION_IGNORE);
/* Clear the 'loading' indicators above */
......
......@@ -4607,12 +4607,11 @@ class template:
except NoLoginsError, e:
return EmulabResponse(RESPONSE_REFUSED, output=str(e))
argerror = CheckRequiredArgs(argdict, ("guid", "instance"))
argerror = CheckRequiredArgs(argdict, ("instance",))
if (argerror):
return argerror
if not (re.match("^[-\w\/]*$", argdict["guid"]) and
re.match("^[-\w]*$", argdict["instance"])):
if not (re.match("^[-\w]*$", argdict["instance"])):
return EmulabResponse(RESPONSE_BADARGS,
output="Improperly formed arguments")
......@@ -4623,11 +4622,12 @@ class template:
argstr += " -i "
argstr += escapeshellarg(val)
pass
elif opt == "run":
argstr += " -r "
argstr += escapeshellarg(val)
pass
pass
argstr += " "
argstr += str(argdict["guid"])
(exitval, output) = runcommand(TBDIR +
"/bin/template_export " + argstr)
if exitval:
......
......@@ -1878,15 +1878,15 @@ class template_export:
def apply(self):
try:
opts, req_args = getopt.getopt(self.argv, "i:", [ "help" ]);
opts, req_args = getopt.getopt(self.argv, "i:r:", [ "help" ]);
pass
except getopt.error, e:
print e.args[0]
self.usage();
return -1;
guid = None
params = {}
instance = None
params = {}
for opt, val in opts:
if opt in ("-h", "--help"):
......@@ -1894,33 +1894,26 @@ class template_export:
return 0
elif opt == "-i":
params["instance"] = val
instance = val
pass
elif opt == "-r":
params["run"] = val
pass
pass
# Try to infer the template guid/vers from the current path.
if len(req_args) == 0:
guid = infer_guid(os.getcwd())
if guid == None:
self.usage();
return -1
pass
elif len(req_args) == 1:
guid = req_args[0]
pass
else:
if instance == None:
self.usage();
return -1
params["guid"] = guid
rval,response = do_method("template", "export", params);
return rval;
def usage(self):
print "template_export -i instance_id [<guid/vers>]";
print "template_export [-r runidx] -i instance_id";
print "where:";
print " -i - Export specific template instance (idx)";
print " guid - Template GUID";
print " -r - Optional run index to export";
print ""
print "Environment:"
print " cwd The template GUID will be inferred from the current"
......
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