Commit 2be50e09 authored by Leigh Stoller's avatar Leigh Stoller

Add usage tracking. Currently we have history tables for aggregates,

slivers and tickets. There is no way to look into these tables yet.
Need to do something about a web interface to Geni before too long.
parent f7e6843b
......@@ -193,3 +193,64 @@ CREATE TABLE `version_info` (
PRIMARY KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
REPLACE INTO `version_info` VALUES ('dbrev', '0');
DROP TABLE IF EXISTS `sliver_history`;
CREATE TABLE `sliver_history` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`slice_hrn` varchar(256) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
`creator_hrn` varchar(256) NOT NULL default '',
`resource_uuid` varchar(40) NOT NULL default '',
`resource_type` varchar(40) NOT NULL default '',
`created` datetime default NULL,
`destroyed` datetime default NULL,
`component_uuid` varchar(40) default NULL,
`component_hrn` varchar(256) default NULL,
`aggregate_uuid` varchar(40) default NULL,
`rspec_string` text,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `aggregate_history`;
CREATE TABLE `aggregate_history` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`type` varchar(40) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`slice_hrn` varchar(256) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
`creator_hrn` varchar(256) NOT NULL default '',
`created` datetime default NULL,
`destroyed` datetime default NULL,
`aggregate_uuid` varchar(40) default NULL,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `ticket_history`;
CREATE TABLE `ticket_history` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`owner_uuid` varchar(40) NOT NULL default '',
`owner_hrn` varchar(256) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`slice_hrn` varchar(256) NOT NULL default '',
`created` datetime default NULL,
`redeemed` datetime default NULL,
`expired` datetime default NULL,
`released` datetime default NULL,
`component_uuid` varchar(40) NOT NULL default '',
`component_hrn` varchar(256) default NULL,
`rspec_string` text,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......@@ -16,7 +16,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm \
GeniTicket.pm GeniSliver.pm GeniCredential.pm \
GeniComponent.pm GeniCH.pm GeniEmulab.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \
GeniUtil.pm GeniRegistry.pm
GeniUtil.pm GeniRegistry.pm GeniUsage.pm
SBIN_SCRIPTS = plabnodewrapper plabslicewrapper
SCRIPTS = addnode.pl
......
......@@ -164,7 +164,15 @@ sub Create($$$$$$)
$certificate->Delete();
return undef;
}
return GeniAggregate->Lookup($idx);
my $aggregate = GeniAggregate->Lookup($idx);
return undef
if (!defined($aggregate));
if (GeniUsage->NewAggregate($aggregate, $slice, $owner)) {
print STDERR "GeniAggregate::Create: ".
"GeniUsage->NewAggregate($aggregate) failed\n";
}
return $aggregate;
}
# accessors
sub field($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'AGGREGATE'}->{$_[1]}); }
......@@ -188,9 +196,9 @@ sub resource_type($) { return field($_[0], "type"); }
# Destroy all the slivers in the aggregate, and then the aggregate if there
# is nothing in it. Leave it around if something goes wrong.
#
sub Delete($)
sub Delete($$)
{
my ($self) = @_;
my ($self, $purge) = @_;
my $broken = 0;
return -1
......@@ -207,7 +215,7 @@ sub Delete($)
$broken++;
last;
}
if ($sliver->Delete() != 0) {
if ($sliver->Delete($purge) != 0) {
print STDERR "Could not delete $sliver from $self\n";
$sliver->SetStatus("broken");
$broken++;
......@@ -217,6 +225,10 @@ sub Delete($)
return -1
if ($broken);
if (GeniUsage->DestroyAggregate($self, $purge)) {
print STDERR "GeniAggregate::Delete: ".
"GeniUsage->DestroyAggregate($self) failed\n";
}
my $idx = $self->idx();
my $uuid = $self->uuid();
......@@ -362,14 +374,22 @@ sub SetAggregate($$)
return -1
if (! (ref($self) && ref($aggregate)));
my $idx = $self->idx();
my $agg_idx = $aggregate->idx();
my $idx = $self->idx();
my $agg_idx = $aggregate->idx();
my $agg_uuid = $aggregate->uuid();
return -1
if (!DBQueryWarn("update geni_aggregates set ".
" aggregate_idx='$agg_idx' ".
"where idx='$idx'"));
if (!DBQueryWarn("update aggregate_history set ".
" aggregate_uuid='$agg_uuid' ".
"where idx='$idx'")) {
print STDERR "GeniAggregate::SetAggregate: ".
"Failed to update aggregate_history for $self\n";
}
$self->{'AGGREGATE'}->{'aggregate_idx'} = $agg_idx;
$self->{'PARENT'} = $aggregate;
return 0;
......@@ -941,7 +961,7 @@ sub Create($$$$$$)
bad:
$tunnel->Destroy()
if (defined($tunnel));
$aggregate->Delete()
$aggregate->Delete(1)
if (defined($aggregate));
return undef;
}
......
......@@ -375,7 +375,7 @@ sub GetTicket($)
my $existing_ticket = GeniTicket->LookupForSlice($slice);
if (defined($existing_ticket)) {
print STDERR "Releasing existing ticket $existing_ticket\n";
if ($existing_ticket->Release() != 0) {
if ($existing_ticket->Release(TICKET_EXPIRED) != 0) {
print STDERR "Error releasing existing ticket $existing_ticket\n";
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR);
......@@ -621,7 +621,7 @@ sub GetTicket($)
bad:
# Release will free the nodes.
if (defined($ticket)) {
$ticket->Release();
$ticket->Release(TICKET_PURGED);
}
elsif (@dealloc) {
system("export NORELOAD=1; $NFREE -x -q $pid $eid @dealloc");
......@@ -677,7 +677,7 @@ sub RedeemTicket($)
# Do not redeem an expired ticket, kill it now.
#
if ($ticket->Expired()) {
$ticket->Release();
$ticket->Release(TICKET_EXPIRED);
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_EXPIRED, undef,
"Ticket has expired");
......@@ -694,7 +694,7 @@ sub RedeemTicket($)
#
my $aggregate = GeniAggregate->SliceAggregate($slice);
if (defined($aggregate)) {
$ticket->Release();
$ticket->Release(TICKET_EXPIRED);
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Already have an aggregate for slice");
......@@ -1026,7 +1026,7 @@ sub ModifySliver($$$$$$)
foreach my $s (values(%linklist)) {
if (! exists($rspec->{'link'}->{$s->hrn()})) {
$s->UnProvision();
$s->Delete();
$s->Delete(0);
next;
}
......@@ -1063,7 +1063,7 @@ sub ModifySliver($$$$$$)
goto bad;
}
my $sliver = GeniSliver::Node->Create($slice,
$owner->uuid(),
$owner,
$resource_uuid,
$ref);
if (!defined($sliver)) {
......@@ -1164,7 +1164,7 @@ sub ModifySliver($$$$$$)
goto bad;
}
my $sliver = GeniSliver::Interface->Create($slice,
$owner->uuid(),
$owner,
$interface->uuid(),
$nodeobject,
$ref);
......@@ -1258,7 +1258,7 @@ sub ModifySliver($$$$$$)
# The last step is to delete the ticket, since it is no longer needed.
# and will cause less confusion if it is not in the DB.
#
if ($ticket->Delete() != 0) {
if ($ticket->Delete(TICKET_REDEEMED) != 0) {
print STDERR "Error deleting $ticket for $slice\n";
}
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
......@@ -1285,14 +1285,14 @@ sub ModifySliver($$$$$$)
foreach my $sliver (values(%slivers)) {
$sliver->UnProvision()
if (! $impotent);
$sliver->Delete();
$sliver->Delete(1);
}
if (values(%toalloc)) {
my @list = values(%toalloc);
system("export NORELOAD=1; $NFREE -x -q $pid $eid @list");
}
$aggregate->Delete()
$aggregate->Delete(1)
if (defined($aggregate) && !defined($object));
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, $message);
......@@ -1337,7 +1337,7 @@ sub ReleaseTicket($)
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse();
}
if ($ticket->Release() != 0) {
if ($ticket->Release(TICKET_RELEASED) != 0) {
print STDERR "Error releasing $ticket\n";
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR);
......@@ -1493,7 +1493,7 @@ sub DeleteSliver($)
"Could not unprovision sliver");
goto bad;
}
if ($aggregate->Delete() != 0) {
if ($aggregate->Delete(0) != 0) {
$response = GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not delete sliver");
goto bad;
......@@ -2271,7 +2271,7 @@ sub CleanupDeadSlice($;$)
print STDERR "Could not UnProvision $aggregate\n";
return -1;
}
if ($aggregate->Delete() != 0) {
if ($aggregate->Delete(0) != 0) {
print STDERR "Could not delete $aggregate\n";
return -1;
}
......@@ -2281,7 +2281,7 @@ sub CleanupDeadSlice($;$)
print STDERR "Could not UnProvision $aggregate\n";
return -1;
}
if ($aggregate->Delete() != 0) {
if ($aggregate->Delete(0) != 0) {
print STDERR "Could not delete $aggregate\n";
return -1;
}
......@@ -2300,7 +2300,7 @@ sub CleanupDeadSlice($;$)
print STDERR "Could not UnProvision $sliver\n";
return -1;
}
if ($sliver->Delete() != 0) {
if ($sliver->Delete(0) != 0) {
print STDERR "Could not delete $sliver\n";
return -1;
}
......@@ -2317,7 +2317,7 @@ sub CleanupDeadSlice($;$)
foreach my $ticket (@tickets) {
# print STDERR "Releasing $ticket\n";
if ($ticket->Release() != 0) {
if ($ticket->Release(TICKET_EXPIRED) != 0) {
print STDERR "Could not delete $ticket\n";
return -1;
}
......
......@@ -22,6 +22,7 @@ use GeniSlice;
use GeniCredential;
use GeniCertificate;
use GeniAggregate;
use GeniUsage;
# Hate to import all this crap; need a utility library.
use libdb qw(TBGetUniqueIndex);
use libtestbed;
......@@ -148,7 +149,7 @@ sub Stringify($)
#
sub Create($$$$$$$$;$$$)
{
my ($class, $slice, $owner_uuid, $uuid, $resource_uuid, $resource_type,
my ($class, $slice, $owner, $uuid, $resource_uuid, $resource_type,
$hrn, $nickname,
$rspec, $credential, $component) = @_;
my @insert_data = ();
......@@ -182,6 +183,7 @@ sub Create($$$$$$$$;$$$)
}
}
my $slice_uuid = $slice->uuid();
my $owner_uuid = $owner->uuid();
# Now tack on other stuff we need.
push(@insert_data, "created=now()");
......@@ -219,6 +221,11 @@ sub Create($$$$$$$$;$$$)
my $sliver = GeniSliver->Lookup($idx);
return undef
if (!defined($sliver));
if (GeniUsage->NewSliver($sliver, $slice, $owner)) {
print STDERR
"GeniSliver::Create: GeniUsage->NewSliver($sliver) failed\n";
}
$sliver->{'CREDENTIAL'} = $credential
if (defined($credential));
......@@ -252,9 +259,9 @@ sub rspec($) { return $_[0]->{'RSPEC'}; }
#
# Delete the sliver. The sliver should not be provisioned when this done.
#
sub Delete($)
sub Delete($$)
{
my ($self) = @_;
my ($self, $purge) = @_;
return -1
if (! ref($self));
......@@ -262,13 +269,17 @@ sub Delete($)
my $idx = $self->idx();
my $uuid = $self->uuid();
if (GeniUsage->DestroySliver($self, $purge)) {
print STDERR
"GeniSliver::Delete: GeniUsage->DestroySliver($self) failed\n";
}
DBQueryWarn("delete from geni_credentials where this_uuid='$uuid'")
or return -1;
DBQueryWarn("delete from geni_certificates where uuid='$uuid'")
or return -1;
DBQueryWarn("delete from geni_slivers where idx='$idx'")
or return -1;
# Delete from cache.
delete($slivers{$idx});
......@@ -293,6 +304,13 @@ sub SetAggregate($$)
" aggregate_uuid='$agg_uuid' ".
"where idx='$idx'"));
if (!DBQueryWarn("update sliver_history set ".
" aggregate_uuid='$agg_uuid' ".
"where idx='$idx'")) {
print STDERR "GeniSliver::SetAggregate: ".
"Failed to update sliver_history for $self\n";
}
$self->{'SLIVER'}->{'aggregate_uuid'} = $agg_uuid;
$self->{'AGGREGATE'} = $aggregate;
return 0;
......@@ -554,9 +572,9 @@ use libdb qw(TBDB_ALLOCSTATE_RES_INIT_DIRTY);
sub Create()
{
my ($class, $slice, $user_uuid, $rspec, $credential, $component) = @_;
my ($class, $slice, $user, $rspec, $credential, $component) = @_;
return GeniSliver->Create($slice, $user_uuid, undef, undef,
return GeniSliver->Create($slice, $user, undef, undef,
"Client", undef, undef, $rspec,
$credential, $component);
}
......@@ -599,7 +617,7 @@ sub Destroy($$)
if ($component->DestroySliver($self, $user) != 0);
# Delete the local object from the DB.
$self->Delete() == 0
$self->Delete(1) == 0
or return -1;
return 0;
......@@ -679,7 +697,7 @@ use libdb qw(TBDB_ALLOCSTATE_RES_INIT_DIRTY);
sub Create($$$$$)
{
my ($class, $slice, $user_uuid, $resource_uuid, $rspec) = @_;
my ($class, $slice, $user, $resource_uuid, $rspec) = @_;
my $virtualization_type = $rspec->{'virtualization_type'};
my $uuid = $resource_uuid;
......@@ -749,7 +767,7 @@ sub Create($$$$$)
$uuid = $vnode->uuid();
$hrn = "${PGENIDOMAIN}." . $vnode->node_id()
}
return GeniSliver->Create($slice, $user_uuid, $uuid, $resource_uuid,
return GeniSliver->Create($slice, $user, $uuid, $resource_uuid,
"Node", $hrn, $nickname, $rspec);
}
......@@ -801,6 +819,7 @@ sub Provision($;$)
return -1;
}
my $redirected = 0;
if (exists($self->rspec()->{'tmcd_server'}) &&
exists($self->rspec()->{'tmcd_nodeid'})) {
my $tmcd_redirect =
......@@ -810,6 +829,7 @@ sub Provision($;$)
if ($node->ModifyReservation({"tmcd_redirect" => $tmcd_redirect})){
return -1;
}
$redirected = 1;
}
#
......@@ -833,6 +853,10 @@ sub Provision($;$)
}
$pnode->ModifyReservation({"genisliver_idx" => $self->idx()});
# Not redirected. Use local tmcd anyway.
$node->ModifyReservation({"genisliver_idx" => $self->idx()})
if (!$redirected);
# Set it to boot the default OS.
if ($pnode->SelectOS() != 0) {
return -1;
......@@ -911,6 +935,7 @@ sub UnProvision($)
return -1;
}
system("$NFREE -x -q $pid $eid $pnode_id");
$pnode->Refresh();
}
else {
system("$NFREE -q $pid $eid $node_id");
......@@ -1010,14 +1035,14 @@ use Node;
sub Create()
{
my ($class, $slice, $user_uuid,
my ($class, $slice, $user,
$interface_uuid, $node, $rspec) = @_;
my $nickname = $rspec->{'nickname'};
my $hrn = "${PGENIDOMAIN}." .
$node->node_id() . "." . $rspec->{'iface_name'};
return GeniSliver->Create($slice, $user_uuid, $interface_uuid,
return GeniSliver->Create($slice, $user, $interface_uuid,
$node->uuid(), "Interface",
$hrn, $nickname, $rspec);
}
......
......@@ -14,7 +14,7 @@ use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw ( );
@EXPORT = qw (TICKET_PURGED TICKET_EXPIRED TICKET_REDEEMED TICKET_RELEASED);
# Must come after package declaration!
use lib '@prefix@/lib';
......@@ -46,6 +46,12 @@ my $VERIFYCRED = "$TB/sbin/verifygenicred";
my $NFREE = "$TB/bin/nfree";
my $CMCERT = "$TB/etc/genicm.pem";
# Ticket release flags
sub TICKET_PURGED() { return 1; }
sub TICKET_REDEEMED() { return 2; }
sub TICKET_EXPIRED() { return 3; }
sub TICKET_RELEASED() { return 4; }
# Cache of tickets.
my %tickets = ();
......@@ -134,6 +140,8 @@ sub Create($$$$)
$self->{'ticket_uuid'} = undef;
$self->{'slice_uuid'} = $slice->uuid();
$self->{'owner_uuid'} = $owner->uuid();
$self->{'slice_hrn'} = $slice->hrn();
$self->{'owner_hrn'} = $owner->hrn();
$self->{'slice_cert'} = $slice->GetCertificate();
$self->{'owner_cert'} = $owner->GetCertificate();
$self->{'seqno'} = $seqno;
......@@ -167,6 +175,9 @@ sub rspec($) { return field($_[0], "rspec"); }
sub slice_uuid($) { return field($_[0], "slice_uuid"); }
sub target_uuid($) { return field($_[0], "slice_uuid"); }
sub owner_uuid($) { return field($_[0], "owner_uuid"); }
sub slice_hrn($) { return field($_[0], "slice_hrn"); }
sub target_hrn($) { return field($_[0], "slice_hrn"); }
sub owner_hrn($) { return field($_[0], "owner_hrn"); }
sub slice_cert($) { return field($_[0], "slice_cert"); }
sub owner_cert($) { return field($_[0], "owner_cert"); }
sub uuid($) { return field($_[0], "ticket_uuid"); }
......@@ -318,6 +329,8 @@ sub CreateFromSignedTicket($$;$$)
$self->{'ticket_uuid'} = $ticket_uuid;
$self->{'slice_uuid'} = $target_certificate->uuid();
$self->{'owner_uuid'} = $owner_certificate->uuid();
$self->{'slice_hrn'} = $target_certificate->hrn();
$self->{'owner_hrn'} = $owner_certificate->hrn();
$self->{'slice_cert'} = $target_certificate;
$self->{'owner_cert'} = $owner_certificate;
$self->{'ticket_string'} = $ticket_string;
......@@ -351,9 +364,9 @@ sub CreateFromSignedTicket($$;$$)
# Might have to delete this from the DB, as with an error handing out
# a ticket.
#
sub Delete($)
sub Delete($$)
{
my ($self) = @_;
my ($self, $flag) = @_;
return -1
if (! ref($self));
......@@ -365,6 +378,27 @@ sub Delete($)
DBQueryWarn("delete from geni_tickets where idx='$idx'")
or return -1;
if ($flag == TICKET_PURGED) {
GeniUsage->DeleteTicket($self) == 0
or print STDERR "GeniTicket::Delete: ".
"GeniUsage->DeleteTicket($self) failed\n";
}
elsif ($flag == TICKET_REDEEMED) {
GeniUsage->RedeemTicket($self) == 0
or print STDERR "GeniTicket::Delete: ".
"GeniUsage->RedeemTicket($self) failed\n";
}
elsif ($flag == TICKET_RELEASED) {
GeniUsage->ReleaseTicket($self) == 0
or print STDERR "GeniTicket::Delete: ".
"GeniUsage->ReleaseTicket($self) failed\n";
}
elsif ($flag == TICKET_EXPIRED) {
GeniUsage->ExpireTicket($self) == 0
or print STDERR "GeniTicket::Delete: ".
"GeniUsage->ExpireTicket($self) failed\n";
}
delete($tickets{"$idx"});
}
return 0;
......@@ -448,6 +482,11 @@ sub Store($)
DBQueryWarn("insert into geni_tickets set " . join(",", @insert_data))
or return -1;
if (GeniUsage->NewTicket($self)) {
print STDERR
"GeniTicket::Store: GeniUsage->NewTicket($self) failed\n";
}
$tickets{"$idx"} = $self;
$self->{'stored'} = 1;
return 0;
......@@ -576,9 +615,9 @@ sub SliceTickets($$$)
# Release a ticket. Need to release the nodes ...
# Used by the CM.
#
sub Release($)
sub Release($$)
{
my ($self) = @_;
my ($self, $flag) = @_;
return -1
if (! ref($self));
......@@ -588,7 +627,7 @@ sub Release($)
#
# Cannot be any nodes if no experiment.
#
return $self->Delete();
return $self->Delete($flag);
}
my $pid = $experiment->pid();
my $eid = $experiment->eid();
......@@ -616,7 +655,7 @@ sub Release($)
foreach my $node (@nodes) {
$node->Refresh();
}
$self->Delete();
$self->Delete($flag);
return 0;
}
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2009 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniUsage;
#
use strict;
use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw ( );
# Must come after package declaration
use lib '@prefix@/lib';
use GeniDB;
use GeniComponent;
use GeniSlice;
use GeniSliver;
use XML::Simple;
use Data::Dumper;
use File::Temp qw(tempfile);
# Configure variables
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $BOSSNODE = "@BOSSNODE@";
my $OURDOMAIN = "@OURDOMAIN@";
my $PGENIDOMAIN = "@PROTOGENI_DOMAIN@";
#
# Create an entry in the sliver history table.
#
sub NewSliver($$$$)
{
my ($class, $sliver, $slice, $owner) = @_;
my @insert_data = ();
my $sliver_idx = $sliver->idx();
my $sliver_uuid = $sliver->uuid();
my $sliver_hrn = $sliver->hrn();
my $slice_uuid = $slice->uuid();
my $slice_hrn = $slice->hrn();
my $owner_uuid = $owner->uuid();
my $owner_hrn = $owner->hrn();
my $resource_uuid = $sliver->resource_uuid();
my $resource_type = $sliver->resource_type();
# Now tack on other stuff we need.
push(@insert_data, "idx='$sliver_idx'");
push(@insert_data, "uuid='$sliver_uuid'");
push(@insert_data, "hrn=" . DBQuoteSpecial($sliver_hrn));
push(@insert_data, "slice_uuid='$slice_uuid'");
push(@insert_data, "slice_hrn=" . DBQuoteSpecial($slice_hrn));
push(@insert_data, "creator_uuid='$owner_uuid'");
push(@insert_data, "creator_hrn=" . DBQuoteSpecial($owner_hrn));
push(@insert_data, "resource_uuid='$resource_uuid'");
push(@insert_data, "resource_type='$resource_type'");
push(@insert_data, "created=now()");
if (defined($sliver->component_uuid())) {
my $component = $sliver->GetComponent();
if (!defined($component)) {
print STDERR
"GeniUsage::AddSliver: Could not get component for $sliver\n";
}
else {
push(@insert_data, "component_uuid='" . $component->uuid() . "'");
push(@insert_data, "component_hrn='" . $component->hrn() . "'");
}
}
if (defined($sliver->rspec())) {
my $rspec_string = XMLout($sliver->rspec(), RootName => "rspec");
my $safe_rspec = DBQuoteSpecial($rspec_string);
push(@insert_data, "rspec_string=$safe_rspec");
}
# Insert into DB.
if (!DBQueryWarn("insert into sliver_history set " .
join(",", @insert_data))) {
return -1;
}
return 0;
}
#
# Update the destroyed/shutdown times for a sliver.
#
sub DestroySliver($$$)
{
my ($class, $sliver, $purge) = @_;
my $idx = $sliver->idx();
if ($purge) {
#
# Delete, as for errors. No point keeping it in the history.
#
return -1
if (!DBQueryWarn("delete from sliver_history ".
"where idx='$idx'"));
}
else {
return -1
if (!DBQueryWarn("update sliver_history set destroyed=now() ".
"where idx='$idx'"));
}
return 0;
}
#
# Create an entry in the aggregate history table.
#
sub NewAggregate($$$$)
{
my ($class, $aggregate, $slice, $owner) = @_;
my @insert_data = ();
my $aggregate_idx = $aggregate->idx();
my $aggregate_uuid = $aggregate->uuid();
my $aggregate_hrn = $aggregate->hrn();
my $aggregate_type = $aggregate->type();
my $slice_uuid = $slice->uuid();
my $slice_hrn = $slice->hrn();
my $owner_uuid = $owner->uuid();
my $owner_hrn = $owner->hrn();
# Now tack on other stuff we need.
push(@insert_data, "idx='$aggregate_idx'");
push(@insert_data, "uuid='$aggregate_uuid'");
push(@insert_data, "hrn=" . DBQuoteSpecial($aggregate_hrn));
push(@insert_data, "type='$aggregate_type'");
push(@insert_data, "slice_uuid='$slice_uuid'");
push(@insert_data, "slice_hrn=" . DBQuoteSpecial($slice_hrn));
push(@insert_data, "creator_uuid='$owner_uuid'");