Commit 64ec2f64 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents d29aa373 13881629
......@@ -27,9 +27,9 @@ static const char rcsid[] = "$Id: parse_advertisement_rspec.cc,v 1.7 2009-10-21
#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
#ifdef TBROOT
#define SCHEMA_LOCATION TBROOT"/lib/assign/rspec-ad.xsd"
#define SCHEMA_LOCATION TBROOT"/lib/assign/ad.xsd"
#else
#define SCHEMA_LOCATION "rspec-ad.xsd"
#define SCHEMA_LOCATION "ad.xsd"
#endif
/*
......
......@@ -27,9 +27,9 @@ static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.16 2009-10-21 20:49
#define ISSWITCH(n) (n->types.find("switch") != n->types.end())
#ifdef TBROOT
#define SCHEMA_LOCATION TBROOT"/lib/assign/rspec-request.xsd"
#define SCHEMA_LOCATION TBROOT"/lib/assign/request.xsd"
#else
#define SCHEMA_LOCATION "rspec-request.xsd"
#define SCHEMA_LOCATION "request.xsd"
#endif
/*
* XXX: Do I have to release lists when done with them?
......
......@@ -60,7 +60,7 @@ extern tb_sgraph SG; // switch fabric
void score_link(pedge pe,vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode);
void unscore_link(pedge pe,vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode);
bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
pedge &out_edge, bool check_src_iface,
pedge &out_edge, bool flipped, bool check_src_iface,
bool check_dst_iface);
int find_interswitch_path(pvertex src_pv,pvertex dest_pv,
int bandwidth,pedge_path &out_path,
......@@ -240,7 +240,7 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
pedge pe;
// Direct link (have to check both interfaces if they are fixed)
if (find_best_link(dest_pv,pv,vlink,pe,true,true)) {
if (find_best_link(dest_pv,pv,vlink,pe,flipped,true,true)) {
tb_link_info info(tb_link_info::LINK_DIRECT);
info.plinks.push_back(pe);
resolutions.push_back(info);
......@@ -279,9 +279,10 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
}
if (first_link) {
SDEBUG(cerr << " intraswitch: finding first link" << endl;)
// Check only whether the source interface is fixed - this is the
// first link in a multi-hop path
if (!find_best_link(pv,*switch_it,vlink,first,true,false)) {
if (!find_best_link(pv,*switch_it,vlink,first,flipped,true,false)) {
SDEBUG(cerr << " intraswitch failed - no link first" <<
endl;)
// No link to this switch
......@@ -292,7 +293,9 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if (second_link) {
// Check only whether the dest interface is fixed - this is the
// last link in a multi-hop path
if (!find_best_link(dest_pv,*switch_it,vlink,second,false,true)) {
SDEBUG(cerr << " intraswitch: finding second link (" << ")" << endl;)
if (!find_best_link(dest_pv,*switch_it,vlink,second,flipped,
false,true)) {
// No link to this switch
SDEBUG(cerr << " intraswitch failed - no link second" <<
endl;)
......@@ -359,7 +362,8 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if (first_link) {
// Check only whether the source interface is fixed - this is the
// first link in a multi-hop path
if (!find_best_link(pv,*source_switch_it,vlink,first,true,false)) {
if (!find_best_link(pv,*source_switch_it,vlink,first,flipped,
true,false)) {
// No link to this switch
SDEBUG(cerr << " interswitch failed - no first link"
<< endl;)
......@@ -370,7 +374,8 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
if (second_link) {
// Check only whether the dest interface is fixed - this is the
// last link in a multi-hop path
if (!find_best_link(dest_pv,*dest_switch_it,vlink,second,false,true)) {
if (!find_best_link(dest_pv,*dest_switch_it,vlink,second,flipped,
false,true)) {
// No link to tshis switch
SDEBUG(cerr << " interswitch failed - no second link" << endl;)
continue;
......@@ -510,6 +515,7 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
*/
bool flipped = false;
if (vlink->src != vv) {
SDEBUG(cerr << " vlink is flipped" << endl);
flipped = true;
}
......@@ -1461,7 +1467,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
}
bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
pedge &out_edge, bool check_src_iface,
pedge &out_edge, bool flipped, bool check_src_iface,
bool check_dst_iface)
{
pvertex dest_pv;
......@@ -1486,15 +1492,20 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
// If the vlink has a fixed source interface, and it doesn't match
// this plink, skip it
// XXX: Is this gonna break interswtich?
if (vlink->fix_src_iface && check_src_iface) {
if (plink->srciface != vlink->src_iface) {
SDEBUG(cerr << "find_best_link: Fix source: " << plink->srciface
<< " != " << vlink->src_iface << endl);
// Whether we check the 'source' or 'destination' on the vlink against
// the phyisical link's source interface depends on whether we're
// traversing the link if forward or reverse (flipped) order
fstring compare_iface = (flipped?vlink->dst_iface:vlink->src_iface);
if (plink->srciface != compare_iface) {
SDEBUG(cerr << " find_best_link (" << vlink->name <<
"): Fix source: " << plink->srciface << " != " <<
compare_iface << endl);
continue;
} else {
SDEBUG(cerr << "find_best_link: Fix source: " << plink->srciface
<< " == " << vlink->src_iface << endl);
SDEBUG(cerr << " find_best_link (" << vlink->name <<
"): Fix source: " << plink->srciface << " == " <<
compare_iface << endl);
}
}
......@@ -1503,13 +1514,16 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
// XXX: This only works because we always have the node as the 'source'
// of a plink! Shouldn't depend on this!
if (vlink->fix_dst_iface && check_dst_iface) {
if (plink->srciface != vlink->dst_iface) {
SDEBUG(cerr << "find_best_link: Fix dst: " << plink->srciface
<< " != " << vlink->dst_iface << endl);
fstring compare_iface = (flipped?vlink->src_iface:vlink->dst_iface);
if (plink->srciface != compare_iface) {
SDEBUG(cerr << " find_best_link (" << vlink->name <<
"): Fix dst: " << plink->srciface << " != " <<
compare_iface << endl);
continue;
} else {
SDEBUG(cerr << "find_best_link: Fix dst: " << plink->srciface
<< " == " << vlink->dst_iface << endl);
SDEBUG(cerr << " find_best_link (" << vlink->name <<
"): Fix dst: " << plink->srciface << " == " <<
compare_iface << endl);
}
}
......@@ -1562,18 +1576,25 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
best_distance = distance;
found_best = true;
best_users = plink->emulated+plink->nonemulated;
SDEBUG(cerr << " find_best_link: picked " << plink->name <<
" with " << best_users << " users" << endl;)
}
}
}
}
if ((!vlink->emulated) && found_best && (best_users > 0)) {
SDEBUG(cerr << " find_best_link failing (first case) (" <<
vlink->emulated << "," << found_best << "," << best_users <<
")" << endl;)
return false;
}
if (found_best) {
out_edge = best_pedge;
SDEBUG(cerr << " find_best_link succeeding" << endl;)
return true;
} else {
SDEBUG(cerr << " find_best_link failing (second case)" << endl;)
return false;
}
}
......
......@@ -61,7 +61,7 @@ my %aggregates = ();
BEGIN { use GeniUtil; GeniUtil::AddCache(\%aggregates); }
#
# Lookup by idx, or uuid.
# Lookup by URN, idx, or uuid.
#
sub Lookup($$)
{
......@@ -70,11 +70,26 @@ sub Lookup($$)
my $idx;
if (GeniHRN::IsValid($token)) {
return undef if !GeniHRN::Authoritative($token, "@OURDOMAIN@");
my ($authority, $type, $id) = GeniHRN::Parse($token);
return undef if $type ne "sliver";
$idx = $id;
if( GeniHRN::Authoritative($token, "@OURDOMAIN@") ) {
# Very simple: we put the index of our own aggregates right
# in the name.
$idx = $id;
} else {
# Look up the aggregate's certificate.
$token = GeniHRN::Normalise( $token );
$query_result = DBQueryWarn(
"SELECT geni_aggregates.idx FROM geni_aggregates, " .
"geni_certificates WHERE geni_aggregates.uuid = " .
"geni_certificates.uuid AND " .
"geni_certificates.urn='$token';" );
return undef if (! $query_result || !$query_result->numrows);
($idx) = $query_result->fetchrow_array();
}
}
elsif ($token =~ /^\d+$/) {
$idx = $token;
......
......@@ -587,6 +587,29 @@ sub SliverAction($$$$$)
# For now, only allow top level aggregate or the slice
#
my ($slice, $aggregate) = Credential2SliceAggregate($credential);
if ( (!defined($slice)) &&
($credential->target_urn() =~ /\+authority\+cm$/)) {
# administrative credentials are presented.
my $cm_urn = GeniHRN::Generate($OURDOMAIN, "authority", "cm");
if ($cm_urn != $credential->target_urn()) {
return GeniResponse->Create(GENIRESPONSE_FORBIDDEN(), undef,
"Credential target does not match CM URN");
}
if (!defined($slice_urn)) {
return GeniResponse->MalformedArgsResponse("Missing arguments");
}
$slice = GeniSlice->Lookup($slice_urn);
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"No Slice with urn $slice_urn here")
if (!defined($slice));
$aggregate = GeniAggregate->SliceAggregate($slice);
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"No Aggregate here")
if (!defined($aggregate));
}
if (! (defined($slice) && defined($aggregate))) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"No slice or aggregate here");
......
......@@ -34,7 +34,7 @@ use Data::Dumper;
use overload ('""' => 'Stringify');
#
# Lookup by idx or uuid.
# Lookup by URN, idx or uuid.
#
sub Lookup($$)
{
......@@ -43,21 +43,28 @@ sub Lookup($$)
my $idx;
if( GeniHRN::IsValid( $token ) ) {
return undef if !GeniHRN::Authoritative( $token, "@OURDOMAIN@" );
my ($authority, $type, $id) = GeniHRN::Parse( $token );
return undef if $type ne "slice";
# Prefixing @PROTOGENI_DOMAIN@. is horribly ugly, but necessary
# at the moment to maintain database compatibility... this should
# probably go away.
$query_result =
DBQueryWarn("select idx from geni_slices ".
"where hrn='@PROTOGENI_DOMAIN@.$id'");
if( GeniHRN::Authoritative( $token, "@OURDOMAIN@" ) ) {
# Good: this is one of our slices, and we can confidently
# transform the name for direct lookup. This method is
# very general, and will even resolve a URN to a (deprecated)
# pre-URN slice.
$query_result =
DBQueryWarn("select idx from geni_slices ".
"where hrn='@PROTOGENI_DOMAIN@.$id'");
} else {
# Somebody else's slice. We'll have to look up the slice
# by its certificate, which will work only for post-URN slices.
$query_result = DBQueryWarn(
"SELECT geni_slices.idx FROM geni_slices, geni_certificates " .
"WHERE geni_slices.uuid = geni_certificates.uuid AND " .
"geni_certificates.urn='$token';" );
}
return undef
if (! $query_result || !$query_result->numrows);
return undef if (! $query_result || !$query_result->numrows);
($idx) = $query_result->fetchrow_array();
}
......@@ -279,7 +286,7 @@ sub Lookup($$)
my $idx;
if( GeniHRN::IsValid( $token ) ) {
return undef if !GeniHRN::Authoritative($token, "@OURDOMAIN@");
$token = GeniHRN::Normalise( $token );
my ($authority, $type, $id) = GeniHRN::Parse($token);
return undef if $type ne "sliver";
......@@ -355,6 +362,28 @@ sub LookupByAuthority($$$)
return GeniRegistry::ClientSliver->Lookup($idx);
}
# Returns an array of client slivers belonging which belong to a
# particular slice.
sub LookupBySlice($$)
{
my ($class, $slice) = @_;
my $slice_idx = $slice->idx();
my $query_result;
my @result = ();
$query_result =
DBQueryWarn("select idx from client_slivers ".
"where slice_idx='$slice_idx'");
if ($query_result) {
while (my ($idx) = $query_result->fetchrow_array()) {
my $sliver = GeniRegistry::ClientSliver->Lookup($idx);
if (defined($sliver)) {
push(@result, $sliver);
}
}
}
return @result;
}
#
# Class function to create new Geni slice and return the object.
#
......
......@@ -327,14 +327,20 @@ sub Resolve($)
if ($slice->Lock() != 0) {
return GeniResponse->BusyResponse("slice");
}
my @slivers = GeniRegistry::ClientSliver->LookupBySlice($slice);
my @managers = ();
foreach my $sliver (@slivers) {
push(@managers, $sliver->manager_urn());
}
# Return a blob.
my $blob = { "hrn" => $slice->hrn(),
"uuid" => $slice->uuid(),
"creator_uuid" => $slice->creator_uuid(),
"gid" => $slice->cert(),
"urn" => GeniHRN::Generate( $OURDOMAIN,
"slice",
$slice->slicename() )
"urn" => GeniHRN::Generate($OURDOMAIN,
"slice",
$slice->slicename() ),
"component_managers" => \@managers
};
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
......
......@@ -267,16 +267,17 @@ sub CreateFromLocal($$$)
}
#
# XXX Form hrn from the domain.
# This mirrors the code in GeniSA.pm
#
my $hrn = "${PGENIDOMAIN}.slices." . $experiment->idx();
my $urn = GeniHRN::Generate( "@OURDOMAIN@", "slice",
"slices." . $experiment->idx() );
my $hrn = "CE" . $experiment->idx();
my $urn = GeniHRN::Generate("@OURDOMAIN@", "slice", $hrn);
$hrn = "${PGENIDOMAIN}.${hrn}";
#
# Generate a certificate.
#
$certificate = GeniCertificate->Create("slice", $urn, $hrn, $user->email());
$certificate = GeniCertificate->Create("slice", $urn, $hrn,
$user->email());
if (!defined($certificate)) {
print STDERR "GeniSlice::CreateFromLocal: ".
"Could not generate new certificate $experiment\n";
......
......@@ -57,7 +57,7 @@ my %slivers = ();
BEGIN { use GeniUtil; GeniUtil::AddCache(\%slivers); }
#
# Lookup by idx, or uuid.
# Lookup by URN, idx, or uuid.
#
sub Lookup($$)
{
......@@ -66,11 +66,26 @@ sub Lookup($$)
my $idx;
if (GeniHRN::IsValid($token)) {
return undef if !GeniHRN::Authoritative($token, "@OURDOMAIN@");
my ($authority, $type, $id) = GeniHRN::Parse($token);
return undef if $type ne "sliver";
$idx = $id;
if( GeniHRN::Authoritative($token, "@OURDOMAIN@") ) {
# Very simple: we put the index of our own slivers right
# in the name.
$idx = $id;
} else {
# Look up the slivers's certificate.
$token = GeniHRN::Normalise( $token );
$query_result = DBQueryWarn(
"SELECT geni_slivers.idx FROM geni_slivers, " .
"geni_certificates WHERE geni_slivers.uuid = " .
"geni_certificates.uuid AND " .
"geni_certificates.urn='$token';" );
return undef if (! $query_result || !$query_result->numrows);
($idx) = $query_result->fetchrow_array();
}
}
elsif ($token =~ /^\d+$/) {
$idx = $token;
......
......@@ -76,6 +76,7 @@ sub Lookup($$)
my $query_result;
if (GeniHRN::IsValid($token)) {
# We don't attempt to handle tickets for foreign authorities.
return undef if !GeniHRN::Authoritative($token, "@OURDOMAIN@");
my ($authority, $type, $id) = GeniHRN::Parse($token);
......
......@@ -57,7 +57,7 @@ sub mysystem($)
}
#
# Lookup by idx, or uuid.
# Lookup by URN, idx, or uuid.
#
sub Lookup($$;$)
{
......@@ -69,30 +69,40 @@ sub Lookup($$;$)
if (!defined($includelocal));
if( GeniHRN::IsValid( $token ) ) {
return undef if !GeniHRN::Authoritative( $token, $OURDOMAIN );
$token = GeniHRN::Normalise( $token );
my ($authority, $type, $id) = GeniHRN::Parse( $token );
return undef if $type ne "user";
$query_result =
DBQueryWarn("select idx from geni_users ".
"where hrn='${PGENIDOMAIN}.$id' and status='active'");
return undef
if (!$query_result);
if (!$query_result->numrows) {
return undef
if (!$includelocal);
if( GeniHRN::Authoritative( $token, "@OURDOMAIN@" ) ) {
# A local name, so look only for local users...
$query_result =
DBQueryWarn("select idx from geni_users ".
"where hrn='${PGENIDOMAIN}.$id' " .
"and status='active'");
#
# Check Emulab users table.
#
my $user = User->Lookup($id);
return undef
if (!defined($user));
return GeniUser->CreateFromLocal($user);
if (!$query_result);
if (!$query_result->numrows) {
return undef
if (!$includelocal);
#
# Check Emulab users table.
#
my $user = User->Lookup($id);
return undef
if (!defined($user));
return GeniUser->CreateFromLocal($user);
}
} else {
# A foreign name: check against names in certificates.
$query_result = DBQueryWarn(
"SELECT geni_users.idx FROM geni_users, geni_certificates " .
"WHERE geni_users.uuid = geni_certificates.uuid AND " .
"geni_certificates.urn = '$token';" );
return undef unless $query_result and $query_result->numrows;
}
($idx) = $query_result->fetchrow_array();
}
......
......@@ -31,17 +31,7 @@
<xs:element ref="rspec:services"/>
</xs:choice>
</xs:choice>
<xs:attribute name="virtualization_type">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="raw"/>
<xs:enumeration value="trellis-vserver"/>
<xs:enumeration value="planetlab-vserver"/>
<xs:enumeration value="emulab-vnode"/>
<xs:enumeration value="bgpmux"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="virtualization_type"/>
<xs:attributeGroup ref="rspec:ComponentName"/>
</xs:complexType>
<xs:element name="subnode_of" type="xs:string"/>
......@@ -64,16 +54,7 @@
<xs:element ref="rspec:packet_loss"/>
</xs:choice>
</xs:choice>
<xs:attribute name="virtualization_type">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="raw"/>
<xs:enumeration value="trellis-vserver"/>
<xs:enumeration value="planetlab-vserver"/>
<xs:enumeration value="emulab-vnode"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="virtualization_type"/>
<xs:attributeGroup ref="rspec:ComponentName"/>
</xs:complexType>
<xs:element name="interface_ref">
......
......@@ -18,8 +18,7 @@ LinkSpec = element link { LinkContents }
NodeContents =
# Each node has exactly one virtualization technology, which we simply
# enumerate here
attribute virtualization_type { "raw" | "trellis-vserver" |
"planetlab-vserver" | "emulab-vnode" | "bgpmux" }? &
attribute virtualization_type { text }? &
# Each node may be the subnode of (physically located within) another.
# In advertisements, this is the URN of the other component.
......@@ -42,8 +41,7 @@ NodeContents =
LinkContents =
# Each link has exactly one virtualization technology, which we simply
# enumerate here
attribute virtualization_type { "raw" | "trellis-vserver" |
"planetlab-vserver" | "emulab-vnode" }? &
attribute virtualization_type { text }? &
# Link types
LinkType+ &
# The interfaces which this link spans.
......
......@@ -22,17 +22,7 @@
<xs:group ref="rspec:NodeTypeList"/>
<xs:element ref="rspec:interface"/>
</xs:choice>
<xs:attribute name="virtualization_type">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="raw"/>
<xs:enumeration value="trellis-vserver"/>
<xs:enumeration value="planetlab-vserver"/>
<xs:enumeration value="emulab-vnode"/>
<xs:enumeration value="bgpmux"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="virtualization_type"/>
<xs:attributeGroup ref="rspec:VirtualName"/>
<xs:attributeGroup ref="rspec:ComponentName"/>
<xs:attribute name="colocate"/>
......@@ -66,16 +56,7 @@
</xs:choice>
</xs:choice>
</xs:choice>
<xs:attribute name="virtualization_type">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="raw"/>
<xs:enumeration value="trellis-vserver"/>
<xs:enumeration value="planetlab-vserver"/>
<xs:enumeration value="emulab-vnode"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="virtualization_type"/>
<xs:attribute name="link_type"/>
<xs:attributeGroup ref="rspec:VirtualName"/>
<xs:attribute name="sliver_id" use="required"/>
......
......@@ -22,17 +22,7 @@
<xs:group ref="rspec:NodeTypeList"/>
<xs:element ref="rspec:interface"/>
</xs:choice>
<xs:attribute name="virtualization_type">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="raw"/>
<xs:enumeration value="trellis-vserver"/>
<xs:enumeration value="planetlab-vserver"/>
<xs:enumeration value="emulab-vnode"/>
<xs:enumeration value="bgpmux"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="virtualization_type"/>
<xs:attributeGroup ref="rspec:VirtualName"/>
<xs:attributeGroup ref="rspec:ComponentName"/>
<xs:attribute name="colocate"/>
......@@ -65,16 +55,7 @@
</xs:choice>
</xs:choice>
</xs:choice>