Commit c378c526 authored by Leigh B Stoller's avatar Leigh B Stoller

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

parents 1e9d3053 231fea1f
......@@ -99,7 +99,7 @@ annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name)
{
DOMElement* vnode
= getElementByAttributeValue(this->virtual_root,
"node", "client_id", v_name);
"node", "client_id", v_name);
// If a vnode by that name was found, then go ahead.
// If not, that element should be a link
// We are not terribly concerned about
......@@ -108,48 +108,44 @@ annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name)
if (vnode != NULL) {
if (!vnode->hasAttribute(XStr("generated_by_assign").x())) {
DOMElement* pnode = (this->physical_elements->find(p_name))->second;
if (pnode->hasAttribute(XStr("component_name").x())) {
vnode->setAttribute(XStr("component_name").x(),
pnode->getAttribute(XStr("component_name").x()));
}
vnode->setAttribute(XStr("component_id").x(),
pnode->getAttribute(XStr("component_id").x()));
pnode->getAttribute(XStr("component_id").x()));
vnode->setAttribute(XStr("component_manager_id").x(),
pnode->getAttribute(XStr("component_manager_id").x()));
pnode->getAttribute(XStr("component_manager_id").x()));
}
}
else {
DOMElement* vlink
= getElementByAttributeValue(this->virtual_root,
"link", "client_id", v_name);
"link", "client_id", v_name);
DOMElement* plink = (this->physical_elements->find(p_name))->second;
// If plink is NULL, then it must be a trivial link
// XXX: Add trivial link support?
if (plink == NULL) {
}
annotate_interface (plink, vlink, 0);
annotate_interface (plink, vlink, 1);
DOMElement* hop = create_component_hop(plink, vlink, BOTH, NULL);
#ifndef DISABLE_LINK_ANNOTATION
vlink->appendChild(hop);
vlink->appendChild(hop);
#endif
if (vlink->hasAttribute(XStr("generated_by_assign").x())) {
string str_lan_link
= string(XStr(vlink->getAttribute(XStr("lan_link").x())).c());
= string(XStr(vlink->getAttribute(XStr("lan_link").x())).c());
DOMElement* lan_link
= getElementByAttributeValue(this->virtual_root, "link",
"client_id",
str_lan_link.c_str());
= getElementByAttributeValue(this->virtual_root, "link",
"client_id",
str_lan_link.c_str());
DOMNodeList* component_hops
= vlink->getElementsByTagName(XStr("component_hop").x());
for (int i = 0; i < component_hops->getLength(); i++) {
DOMElement* component_hop
= dynamic_cast<DOMElement*>(component_hops->item(i));
copy_component_hop(lan_link, component_hop);
= vlink->getElementsByTagName(XStr("component_hop").x());
for (unsigned int i = 0; i < component_hops->getLength(); i++) {
DOMElement* component_hop
= dynamic_cast<DOMElement*>(component_hops->item(i));
copy_component_hop(lan_link, component_hop);
}
}
}
......@@ -157,12 +153,15 @@ annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name)
// This is called when an intraswitch or interswitch link has to be annotated
void annotate_rspec_v2::annotate_element (const char* v_name,
list<const char*>* links)
list<const char*>* unordered)
{
// We can't locate interfaces on the switches, so we don't add those
// to the annotation. The warning is only given the one time
static bool gave_apology = false;
// Re-order links to ensure that they are all head-to-tail.
list<const char*>* links = this->reorderLinks(unordered);
// These are the paths from the source to the first switch
// and from the last switch to the destination
const char* psrc_name = links->front();
......@@ -176,10 +175,10 @@ void annotate_rspec_v2::annotate_element (const char* v_name,
// If it is an intra-switch link, the list should now be empty.
links->pop_front();
links->pop_back();
DOMElement* vlink
= getElementByAttributeValue (this->virtual_root, "link",
"client_id", v_name);
"client_id", v_name);
annotate_interface(p_src_switch_link, vlink, 0);
annotate_interface(p_switch_dst_link, vlink, 1);
......@@ -187,7 +186,7 @@ void annotate_rspec_v2::annotate_element (const char* v_name,
DOMElement* prevComponentHop
= create_component_hop (p_src_switch_link, vlink, SOURCE, NULL);
componentHops.push_back(prevComponentHop);
for (DOMElement *prevLinkInPath = p_src_switch_link; !links->empty(); ) {
#ifndef DISABLE_LINK_ANNOTATION
if (!gave_apology) {
......@@ -197,18 +196,19 @@ void annotate_rspec_v2::annotate_element (const char* v_name,
}
#endif
DOMElement* pSwitchSwitchLink
// = ((this->physical_elements)->find(*it))->second;
= find_next_link_in_path (prevLinkInPath, links);
prevComponentHop = create_component_hop (pSwitchSwitchLink, vlink,
NEITHER, prevComponentHop);
NEITHER, prevComponentHop);
prevLinkInPath = pSwitchSwitchLink;
// componentHops.push_back(prevComponentHop);
}
DOMElement* hop = create_component_hop (p_switch_dst_link, vlink,
DESTINATION, prevComponentHop);
DESTINATION, prevComponentHop);
componentHops.push_back(hop);
#ifndef DISABLE_LINK_ANNOTATION
for (int i = 0; i < componentHops.size(); i++) {
for (unsigned int i = 0; i < componentHops.size(); i++) {
vlink->appendChild(componentHops[i]);
}
#endif
......@@ -220,7 +220,6 @@ DOMElement* annotate_rspec_v2::create_component_hop (DOMElement* vlink)
DOMNodeList* ifaces = vlink->getElementsByTagName(XStr("interface_ref").x());
DOMElement* srcIface = dynamic_cast<DOMElement*>(ifaces->item(0));
DOMElement* dstIface = dynamic_cast<DOMElement*>(ifaces->item(1));
string srcIfaceId = XStr(srcIface->getAttribute(XStr("client_id").x())).c();
string dstIfaceId = XStr(dstIface->getAttribute(XStr("client_id").x())).c();
......@@ -248,9 +247,9 @@ DOMElement* annotate_rspec_v2::create_component_hop (DOMElement* vlink)
// Creates a hop from a switch till the next end point.
DOMElement*
annotate_rspec_v2::create_component_hop (const DOMElement* plink,
DOMElement* vlink,
int endpointIface,
const DOMElement* prevHop)
DOMElement* vlink,
int endpointIface,
const DOMElement* prevHop)
{
// We assume the first interface is the source and the second the dest
DOMNodeList* pIfaces =plink->getElementsByTagName(XStr("interface_ref").x());
......@@ -272,10 +271,10 @@ annotate_rspec_v2::create_component_hop (const DOMElement* plink,
// or the direction is guaranteed to be from the node to the switch
DOMElement* plinkSrcIfaceClone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkSrcIface),true));
(dynamic_cast<DOMNode*>(plinkSrcIface),true));
DOMElement* plinkDstIfaceClone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkDstIface),true));
(dynamic_cast<DOMNode*>(plinkDstIface),true));
string plinkSrcIfaceId
= XStr(plinkSrcIface->getAttribute(XStr("component_id").x())).c();
......@@ -294,7 +293,7 @@ annotate_rspec_v2::create_component_hop (const DOMElement* plink,
// Find the destination of the previous component hop
DOMElement* prevHopDstIface
= dynamic_cast<DOMElement*>((prevHop->getElementsByTagName
(XStr("interface_ref").x()))->item(1));
(XStr("interface_ref").x()))->item(1));
string prevHopDstIfaceId
= XStr(prevHopDstIface->getAttribute(XStr("component_id").x())).c();
......@@ -309,13 +308,13 @@ annotate_rspec_v2::create_component_hop (const DOMElement* plink,
// whether a destination interface was specified
if (prevHopDstNodeId == plinkDstNodeId) {
plinkSrcIfaceClone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkDstIface),
true));
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkDstIface),
true));
plinkDstIfaceClone
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkSrcIface),
true));
= dynamic_cast<DOMElement*>(doc->importNode
(dynamic_cast<DOMNode*>(plinkSrcIface),
true));
}
}
......@@ -367,7 +366,7 @@ annotate_rspec_v2::create_component_hop (const DOMElement* plink,
// but it sounds like a dirty way of doing it and is not exactly robust,
// so we shall use the slower, but more robust method
void annotate_rspec_v2::copy_component_hop(DOMElement* lan_link,
DOMElement* component_hop)
DOMElement* component_hop)
{
string lan_link_id
= string(XStr(lan_link->getAttribute(XStr("client_id").x())).c());
......@@ -406,15 +405,15 @@ bool annotate_rspec_v2::has_interface_with_id (string link_client_id, string id)
// Annotates the interfaces on a node making up the end points of a trivial link
void annotate_rspec_v2::annotate_interface (const DOMElement* vlink,
int interface_number)
int interface_number)
{
this->annotate_interface (NULL, vlink, interface_number, true);
}
// Annotates the interfaces on a non-trivial link
void annotate_rspec_v2::annotate_interface (const DOMElement* plink,
const DOMElement* vlink,
int interface_number)
const DOMElement* vlink,
int interface_number)
{
this->annotate_interface (plink, vlink, interface_number, false);
}
......@@ -431,21 +430,22 @@ void annotate_rspec_v2::annotate_interface (const DOMElement* plink,
// 5) Annotate the interface on the virtual node obtained in 2)
// with the interface_id obtained in 4)
void annotate_rspec_v2::annotate_interface (const DOMElement* plink,
const DOMElement* vlink,
int ifaceNumber,
bool isTrivialLink)
const DOMElement* vlink,
int ifaceNumber,
bool isTrivialLink)
{
DOMNodeList* refs = vlink->getElementsByTagName(XStr("interface_ref").x());
DOMElement* ref = dynamic_cast<DOMElement*>(refs->item(ifaceNumber));
string ifaceId = XStr(ref->getAttribute(XStr("client_id").x())).c();
// cerr << endl << "Interface: " << ifaceId << endl;
// Get the client_id of the node to which the interface belongs
bool found = false;
string nodeId = this->lookupIface(this->vInterfaceMap, ifaceId, found);
DOMElement* vnode = getElementByAttributeValue(this->virtual_root, "node",
"client_id", nodeId.c_str());
"client_id", nodeId.c_str());
DOMElement* decl = getElementByAttributeValue(vnode, "interface",
"client_id", ifaceId.c_str());
"client_id", ifaceId.c_str());
string physNodeId = XStr(vnode->getAttribute(XStr("component_id").x())).c();
......@@ -507,22 +507,29 @@ annotate_rspec_v2::copy_component_spec(const DOMElement* src, DOMElement* dst)
// Assign sometimes reverses the links on the path
// from the source to destination,
// so you need to look at the entire path to find the next link
DOMElement* annotate_rspec_v2::find_next_link_in_path (DOMElement *prev,
list<const char*>* links)
// WARNING: This removes the link in the path from the list of link
DOMElement*
annotate_rspec_v2::find_next_link_in_path (DOMElement *prev,
list<const char*>* links)
{
list<const char*>::iterator it;
DOMElement* link = NULL;
for (it = links->begin(); it != links->end(); ++it) {
link = (this->physical_elements->find(*it))->second;
// We assume as we have done throughout that the first interface
// represents the source of the link and the second interface
// is the destination.
string linkSrc = this->getNodeForNthInterface(link, 0);
string linkDst = this->getNodeForNthInterface(link, 1);
string prevDst = this->getNodeForNthInterface(prev, 1);
if (linkSrc == prevDst || linkDst == prevDst) {
string linkSrc = this->getNthInterface(link, 0);
string linkDst = this->getNthInterface(link, 1);
string prevSrc = this->getNthInterface(prev, 0);
string prevDst = this->getNthInterface(prev, 1);
if ((linkSrc == prevDst && linkDst != prevSrc)
|| (linkSrc == prevSrc && linkDst != prevDst)
|| (linkDst == prevSrc && linkSrc != prevDst)
|| (linkDst == prevDst && linkSrc != prevSrc)) {
links->remove(*it);
break;
}
......@@ -537,7 +544,7 @@ void annotate_rspec_v2::cleanup()
// Remove generated links
vector<DOMElement*> generated_links
= getElementsHavingAttribute(this->virtual_root, "link",
"generated_by_assign");
"generated_by_assign");
for (it = generated_links.begin(); it < generated_links.end(); it++) {
DOMNode* generated_link = dynamic_cast<DOMNode*>(*it);
dynamic_cast<DOMNode*>(this->virtual_root)->removeChild(generated_link);
......@@ -546,7 +553,7 @@ void annotate_rspec_v2::cleanup()
// Remove generated nodes
vector<DOMElement*> generated_nodes
= getElementsHavingAttribute(this->virtual_root, "node",
"generated_by_assign");
"generated_by_assign");
for (it = generated_nodes.begin(); it < generated_nodes.end(); it++) {
DOMNode* generated_link = dynamic_cast<DOMNode*>(*it);
dynamic_cast<DOMNode*>(this->virtual_root)->removeChild(generated_link);
......@@ -595,7 +602,7 @@ const DOMElement*
annotate_rspec_v2::getIfaceOnNode(const DOMElement* plink, string nodeId)
{
DOMNodeList* refs = plink->getElementsByTagName(XStr("interface_ref").x());
for (int i = 0; i < refs->getLength(); i++) {
for (unsigned int i = 0; i < refs->getLength(); i++) {
bool found = false;
DOMElement* ref = dynamic_cast<DOMElement*>(refs->item(i));
string ifaceId = XStr(ref->getAttribute(XStr("component_id").x())).c();
......@@ -607,21 +614,19 @@ annotate_rspec_v2::getIfaceOnNode(const DOMElement* plink, string nodeId)
return NULL;
}
// Returns the node id for the nth interface on a link
string annotate_rspec_v2::getNodeForNthInterface (const DOMElement* link,
int number)
// Returns the component id for the nth interface on a link
string annotate_rspec_v2::getNthInterface (const DOMElement* link, int number)
{
bool found = false;
DOMNodeList* ifaces = link->getElementsByTagName(XStr("interface_ref").x());
if (ifaces->getLength() < number) {
if ((int)ifaces->getLength() < number) {
cerr << "*** Link "
<< XStr(link->getAttribute(XStr("component_id").x())).c()
<< " has only " << ifaces->getLength() << " interfaces. "
<< "Interface number " << number << " requested." << endl;
exit(EXIT_FATAL);
}
string ifaceId = XStr(link->getAttribute(XStr("component_id").x())).c();
return (this->lookupIface(this->pInterfaceMap, ifaceId, found));
DOMElement* iface = dynamic_cast<DOMElement*>(ifaces->item(number));
return string(XStr(iface->getAttribute(XStr("component_id").x())).c());
}
// Annotates the end point interface if found
......@@ -664,4 +669,29 @@ string annotate_rspec_v2::getShortInterfaceName (string interface)
return interface.substr(loc+1);
}
// Re-orders the links so that all the links on an interswitch link
// are in the correct order
// WARNING: This will distroy the input list
// NOTE: The pointer to the list returned by this should be freed
list<const char*>*
annotate_rspec_v2::reorderLinks (list<const char*>* links)
{
list<const char*> *ordered = new list<const char*>();
// list<const char*>::iterator it;
string link = links->front();
links->pop_front();
DOMElement* prev = ((this->physical_elements)->find(link.c_str()))->second;
ordered->push_back(link.c_str());
while(!links->empty()) {
prev = this->find_next_link_in_path(prev, links);
string* link
= new string(XStr(prev->getAttribute(XStr("component_id").x())).c());
links->remove(link->c_str());
ordered->push_back(link->c_str());
}
return ordered;
}
#endif
......@@ -114,9 +114,8 @@ class annotate_rspec_v2 : public annotate_rspec
const xercesc::DOMElement*
getIfaceOnNode(const xercesc::DOMElement* plink, std::string physNodeId);
// Retuns the id of the physical source node
// for the nth interface of a link
std::string getNodeForNthInterface (const xercesc::DOMElement* link, int n);
// Retuns the component id of the nth interface of a link
std::string getNthInterface (const xercesc::DOMElement* link, int n);
// Annotates the end point of a link
bool annotate_endpoint(xercesc::DOMElement* iface, std::string virtId);
......@@ -126,6 +125,11 @@ class annotate_rspec_v2 : public annotate_rspec
// Adds a fixed interface element to an interface
void addFixedInterface(xercesc::DOMElement* interface,std::string shortname);
// Orders the links in the specified list of links from head to tail
// The first element in the list MUST be the head
// WARNING: This will destroy in the input list
std::list<const char*>* reorderLinks (std::list<const char*>* links);
};
#endif //for __ANNOTATE_RSPEC_H
......
......@@ -38,7 +38,7 @@ namespace featuredesire {
class tb_featuredesire_policy {
public:
tb_featuredesire_policy(): allowable(true), limited_use(false),
min_use(0.0f), max_use(0.0f) { ; };
max_use(0.0f), min_use(0.0f) { ; };
/*
* Functions for maintaining FD policy state. Inline, since they're
* so simple.
......
......@@ -135,7 +135,6 @@ int parse_request(tb_vgraph &vg, char *filename) {
doc = domParser->getDocument();
request_root = doc->getDocumentElement();
bool is_physical;
string type = XStr (request_root->getAttribute(XStr("type").x())).c();
if (type != "request") {
cout << "*** RSpec type must be \"request\" in " << filename
......@@ -154,7 +153,7 @@ int parse_request(tb_vgraph &vg, char *filename) {
rspecParser = new rspec_parser_v2(RSPEC_TYPE_REQ);
break;
default:
cerr << "*** Unsupported rspec ver. " << rspecVersion
cout << "*** Unsupported rspec ver. " << rspecVersion
<< " ... Aborting " << endl;
exit(EXIT_FATAL);
}
......@@ -266,7 +265,7 @@ bool populate_node(DOMElement* elt,
bool isStatic = false;
bool isUnlimited = false;
if (typeCount > 1) {
cerr << "*** Too many node types (" << typeCount << ") on "
cout << "*** Too many node types (" << typeCount << ") on "
<< virtualId << " (allowed 1) ... Aborting " << endl;
return false;
}
......@@ -326,8 +325,8 @@ bool populate_node(DOMElement* elt,
if (no_type) {
// If they gave no type, just assume it's a PC for
// now. This is not really a good assumption.
cerr << "WARNING: No type information found on node. "
<< "Defaulting to " << typeName.c_str() << endl;
XMLDEBUG("WARNING: No type information found on node. "
<< "Defaulting to " << typeName.c_str() << endl);
}
v = new tb_vnode(virtualId.c_str(), typeName.c_str(), typeSlots);
......@@ -418,8 +417,8 @@ bool populate_node(DOMElement* elt,
* Pull nodes from the document, and populate assign's own data structures
*/
bool populate_nodes(DOMElement *root,
tb_vgraph &vg, map< pair<string, string>,
pair<string, string> >* fixed_interfaces) {
tb_vgraph &vg, map< pair<string, string>,
pair<string, string> >* fixed_interfaces) {
bool is_ok = true;
/*
* Get a list of all nodes in this document
......@@ -428,7 +427,7 @@ bool populate_nodes(DOMElement *root,
int nodeCount = nodes->getLength();
XMLDEBUG("Found " << nodeCount << " nodes in rspec" << endl);
for (size_t i = 0; i < nodeCount; i++) {
for (unsigned i = 0; i < nodeCount; i++) {
DOMNode *node = nodes->item(i);
// This should not be able to fail, because all elements in
// this list came from the getElementsByTagName() call
......@@ -608,18 +607,18 @@ bool populate_link (DOMElement* elt,
}
if (dstNode == "" || dstIface == "") {
cout << "*** No destination node found on interface for link "
<< virtualId << endl;
<< virtualId << endl;
return false;
}
if (vname2vertex.find(srcNode.c_str()) == vname2vertex.end()) {
cout << "*** Bad link " << virtualId
<< ", non-existent source node " << srcNode << endl;
<< ", non-existent source node " << srcNode << endl;
return false;
}
if (vname2vertex.find(dstNode.c_str()) == vname2vertex.end()) {
cout << "*** Bad link " << virtualId
<< ", non-existent destination node " << dstNode << endl;
<< ", non-existent destination node " << dstNode << endl;
return false;
}
......@@ -658,6 +657,7 @@ bool populate_link (DOMElement* elt,
if (it != fixed_interfaces->end()) {
fix_dstIface = true;
fixed_dstIface = (it->second).second;
}
if (emulated) {
......@@ -738,7 +738,7 @@ bool populate_vclass (struct vclass vclass, tb_vgraph& vg)
if (vclass.type.type == SOFT_VCLASS) {
v = new tb_vclass (XStr(name).f(), vclass.type.weight);
if (v == NULL) {
cerr << "*** Could not create vclass " << vclass.name << endl;
cout << "*** Could not create vclass " << vclass.name << endl;
return false;
}
vclass_map[name] = v;
......@@ -759,7 +759,7 @@ bool populate_vclasses (DOMElement* root, tb_vgraph& vg)
{
bool isOk = true;
vector<struct vclass> vclasses = rspecParser->readVClasses(root);
cerr << "Found " << vclasses.size() << " vclasses." << endl;
XMLDEBUG("Found " << vclasses.size() << " vclasses." << endl);
for (unsigned int i = 0; i < vclasses.size(); i++) {
isOk &= populate_vclass(vclasses[i], vg);
}
......
......@@ -68,7 +68,7 @@ public:
class tb_pclass {
public:
tb_pclass() : name(), size(0), used_members(0), refcount(0), disabled(false),
tb_pclass() : name(), size(0), used_members(0), disabled(false), refcount(0),
is_dynamic(false) {;}
typedef map<fstring,tb_pnodelist*> pclass_members_map;
......
......@@ -79,7 +79,7 @@ void print_solution(const solution &s) {
for (;vit != veit;++vit) {
vn = get(vvertex_pmap,*vit);
if (! s.is_assigned(*vit)) {
cout << "unassigned: " << vn->name << endl;
cout << "unassigned: " << vn->name << endl;
} else {
#ifdef WITH_XML
string node_name = XStr(vn -> name).c();
......@@ -108,7 +108,7 @@ void print_solution(const solution &s) {
vedge_iterator eit,eendit;
tie(eit,eendit) = edges(VG);
for (;eit!=eendit;++eit) {
tb_vlink *vlink = get(vedge_pmap,*eit);
tb_vlink *vlink = get(vedge_pmap,*eit);
#ifdef WITH_XML
if (both_inputs_rspec) {
......@@ -135,7 +135,7 @@ void print_solution(const solution &s) {
#ifdef WITH_XML
if (both_inputs_rspec) {
rspec_annotater->annotate_element((vlink->name).c_str(),
(p->name).c_str());
(p->name).c_str());
if (is_generated)
continue;
}
......
......@@ -115,7 +115,7 @@ node_interface_pair parse_interface_xml(const xercesc::DOMElement* tag);
/*
* Bundle the componentspec attributes together
*/
typedef struct component_spec
struct component_spec
{
string component_manager_uuid;
string component_name;
......@@ -130,7 +130,7 @@ component_spec parse_component_spec (const xercesc::DOMElement* element);
/*
* Bundle the InterfaceSpec attributes together
*/
typedef struct interface_spec
struct interface_spec
{
string virtual_node_id;
string virtual_interface_id;
......
......@@ -64,7 +64,7 @@ notifications. The system defined fields include:
typedef struct {
char *site; /* Which Emulab site. */
char *expt; /* Project and experiment IDs */
char *group; /* User defined group of nodes */
char *group; /* Deprecated */
char *host; /* A specific host (ipaddr) */
char *objtype; /* LINK, TRAFGEN, etc ... */
char *objname; /* link0, cbr0, cbr1, etc ... */
......@@ -72,6 +72,12 @@ notifications. The system defined fields include:
int scheduler; /* A dynamic event to schedule */
} address_tuple;
Important Note: Event groups are *not* implemented by the group field
in the tuple. Rather, they are implemented by adding names to the
objname field treating it as a comma-delimited field. Since names are
not unique, the event is sent to every agent registered under the
group name.
The last field, scheduler, is used internally to route notifications to the
scheduler for an experiment. This is described in more detail below.
......
......@@ -513,9 +513,12 @@ sub Sign($$)
#
# Create a template xml file to sign.
#
my $id = sprintf( "%04X%04X%04X%04X", int( rand( 0x10000 ) ),
int( rand( 0x10000 ) ), int( rand( 0x10000 ) ),
int( rand( 0x10000 ) ) );
my $template =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n".
"<credential xml:id=\"ref1\">\n".
"<credential xml:id=\"ref$id\">\n".
" <type>privilege</type>\n".
" <serial>$idx</serial>\n".
" <owner_gid>$owner_cert</owner_gid>\n".
......
......@@ -16,6 +16,7 @@
import datetime
import getopt
import os
import random
import re
import sys
import tempfile
......@@ -200,11 +201,14 @@ old = Lookup( doc.documentElement, "credential" )
c = doc.createElement( "credential" )
id = 1
while filter( lambda x: x.getAttribute( "xml:id" ) == "ref" + str( id ),
doc.getElementsByTagName( "credential" ) ):
id = id + 1
c.setAttribute( "xml:id", "ref" + str( id ) )
# I really want do loops in Python...
while True:
id = "ref" + '%016X' % random.getrandbits( 64 )
if not filter( lambda x: x.getAttribute( "xml:id" ) == "ref" + str( id ),
doc.getElementsByTagName( "credential" ) ):
break
c.setAttribute( "xml:id", str( id ) )
c.appendChild( Lookup( old, "type" ).cloneNode( True ) )
c.appendChild( SimpleNode( doc, "serial", "1" ) )
......@@ -258,7 +262,7 @@ p.appendChild( old )