Commit 3b673271 authored by Gary Wong's avatar Gary Wong

Add rmblob facility (allowing blob owners to remove their blobs).

parent af71f3e3
......@@ -128,6 +128,7 @@ DROP TABLE IF EXISTS `blobs`;
CREATE TABLE `blobs` (
`uuid` varchar(40) NOT NULL,
`filename` tinytext,
`owner_uid` varchar(8) NOT NULL default '',
PRIMARY KEY (`uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......
#
# Add owner uid to blob table (to allow rmblob)
#
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if( !DBSlotExists( "blobs", "owner_uid" ) ) {
DBQueryFatal( "ALTER TABLE blobs ADD " .
"`owner_uid` varchar(8) NOT NULL default ''" );
}
return 0;
}
1;
......@@ -17,7 +17,7 @@ SUBDIRS = nsgen
BIN_SCRIPTS = delay_config sshtb create_image node_admin link_config \
setdest loghole webcopy linkmon_ctl snmp-if-deref.sh \
template_record spewevents \
wbts_dump mkblob
wbts_dump mkblob rmblob
SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
eventping grantnodetype import_commitlog daemon_wrapper \
opsreboot deletenode node_statewait grabwebcams \
......
......@@ -36,15 +36,23 @@ use libtestbed;
# Handle command-line options.
#
sub usage() {
print STDERR "Usage: $0 <filename>\n";
print STDERR "Usage: $0 <owner-uid> <filename>\n";
exit( 1 );
}
usage() unless @ARGV == 1;
my ( $filename ) = @ARGV;
usage() unless @ARGV == 2;
my ( $uid, $filename ) = @ARGV;
#
# Must taint check!
#
if ($uid =~ /^([-\w #%&*+,.\/:;=?@\[\\\]^{|}]+)$/) {
$uid = $1;
}
else {
print STDERR "Bad character in uid\n";
exit( 1 );
}
if ($filename =~ /^([-\w #%&*+,.\/:;=?@\[\\\]^{|}]+)$/) {
$filename = $1;
}
......@@ -59,7 +67,7 @@ my $uuid = `@UUIDGEN@`;
chomp $uuid;
my $result = DBQueryWarn( "INSERT INTO blobs SET uuid='$uuid', " .
"filename='$filename';" );
"filename='$filename', owner_uid='$uid';" );
unless( $result ) {
print STDERR "Could not insert record.\n";
exit( 1 );
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2010 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use strict;
#
# Configure variables
#
my $TB = "@prefix@";
#
# Turn off line buffering on output
#
$| = 1;
#
# Untaint the path
#
$ENV{'PATH'} = "$TB/bin:$TB/sbin:/bin:/usr/bin:/sbin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# Handle command-line options.
#
sub usage() {
print STDERR "Usage: $0 <owner-uid> <blob-uuid>\n";
exit( 1 );
}
usage() unless @ARGV == 2;
my ( $uid, $uuid ) = @ARGV;
#
# Must taint check!
#
if ($uid =~ /^([-\w #%&*+,.\/:;=?@\[\\\]^{|}]+)$/) {
$uid = $1;
}
else {
print STDERR "Bad character in uid\n";
exit( 1 );
}
if ($uuid =~ /^([-\w]+)$/) {
$uuid = $1;
}
else {
print STDERR "Bad character in uuid\n";
exit( 1 );
}
my $result = DBQueryWarn( "DELETE FROM blobs WHERE uuid='$uuid' AND " .
"owner_uid='$uid';" );
unless( $result ) {
print STDERR "Could not delete record.\n";
exit( 1 );
}
unless( $result->affectedrows == 1 ) {
print STDERR "Permission denied.\n";
exit( 1 );
}
# And clean up the blob_files table (which is only a cache), just in case
# we removed the last reference to a file.
DBQueryWarn( "DELETE blob_files FROM blob_files LEFT OUTER JOIN blobs ON " .
"blob_files.filename=blobs.filename WHERE " .
"blobs.filename IS NULL;" );
exit( 0 );
......@@ -35,7 +35,7 @@ SYMLINKS = node_admin node_reboot os_load create_image node_list \
modexp expinfo node_avail tbuisp expwait template_commit \
template_export template_swapin template_swapout \
template_stoprun template_instantiate template_startrun \
template_checkout node_avail_list mkblob
template_checkout node_avail_list mkblob rmblob
#
# Force dependencies on the scripts so that they will be rerun through
......
......@@ -5748,7 +5748,29 @@ class blob:
if (argerror):
return argerror
(exitval, output) = runcommand( TBDIR + "/bin/mkblob " + argdict[ "filename" ] )
(exitval, output) = runcommand( TBDIR + "/bin/mkblob " + self.uid + " " + argdict[ "filename" ] )
if exitval:
return EmulabResponse( RESPONSE_ERROR, exitval >> 8, output=output )
else:
return EmulabResponse( RESPONSE_SUCCESS, value=0, output=output )
def rmblob( self, version, argdict ):
if version != self.VERSION:
return EmulabResponse(RESPONSE_BADVERSION,
output="Client version mismatch!")
try:
checknologins()
pass
except NoLoginsError, e:
return EmulabResponse(RESPONSE_REFUSED, output=str(e))
argerror = CheckRequiredArgs(argdict, ("uuid",))
if (argerror):
return argerror
(exitval, output) = runcommand( TBDIR + "/bin/rmblob " + self.uid + " " + argdict[ "uuid" ] )
if exitval:
return EmulabResponse( RESPONSE_ERROR, exitval >> 8, output=output )
......
......@@ -150,7 +150,9 @@ API = {
"template_stoprun" : { "func" : "template_stoprun",
"help" : "Stop current experiment run" },
"mkblob" : { "func" : "mkblob",
"help" : "Create a new blob in the blob store" }
"help" : "Create a new blob in the blob store" },
"rmblob" : { "func" : "rmblob",
"help" : "Remove a blob from the blob store" }
};
#
......@@ -2640,6 +2642,43 @@ class mkblob:
return
pass
#
# rmblob
#
class rmblob:
def __init__(self, argv=None):
self.argv = argv;
return
def apply(self):
try:
opts, req_args = getopt.getopt(self.argv, "h", [ "help" ]);
pass
except getopt.error, e:
print e.args[0]
self.usage();
return -1;
for opt, val in opts:
if opt in ("-h", "--help"):
self.usage()
return 0
# Do this after so --help is seen.
if len(req_args) != 1:
self.usage();
return -1;
rval,response = do_method( "blob", "rmblob",
{ "uuid" : req_args[ 0 ] } );
return rval;
def usage(self):
print "rmblob [options] uuid"
wrapperoptions();
return
pass
#
# Infer template guid from path
#
......
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