ptopgen_new.in 6.21 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#!/usr/bin/perl -w

#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#

use strict;
use English;
use Getopt::Std;

13
use lib "@prefix@/lib";
14
use libdb;
15
use emdbi;
16
use libptop_new;
17 18
use GeniXML;

19
sub usage();
20 21 22 23
sub processArgs();
sub consultDatabase();
sub process();
sub printResults();
24
sub printTypeLimits($);
25 26 27 28 29 30

#
# Turn off line buffering on output
#
$| = 1;

31
my $print_xml = 0;
32
my $print_ns = $GeniXML::RSPEC_2_NS;
33
my $typelimitfile;
34
my $debug = 0;
35

36
# Initialize permissions table for the current project
37
emdbi::ClearQueryCount();
38 39 40
processArgs();
consultDatabase();
printResults();
41 42 43
if ($debug) {
    print STDERR "# of Queries: " . emdbi::GetQueryCount() . "\n";
}
44

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
sub usage()
{
    print("Usage: ptopgen [-p pid [-e eid]] [-v] [-r] [-S] [-s switch]\n".
	  "               [-h] [-a] [-m multiplex_factor] [-u] [-d]\n".
	  "               [-c delay_capacity] [-x] [-g (0.1 | 0.2 | 2)]\n".
	  "               [-l type-limit-file] [-1 component_name]\n\n" .
	  "       -p User project. May restrict nodes and osids.\n".
	  "       -e User experiment. Nodes and bandwidth allocated to\n" .
	  "          this experiment are reported as free.\n" .
	  "       -v Include virtual node types\n".
	  "       -r Include widearea nodes\n".
	  "       -S Include simulated node types and flags\n".
	  "       -s Switch to use (UNIMPLEMENTED)\n".
	  "       -h Include shared nodes\n".
	  "       -a Include reserved nodes\n".
	  "       -m Override multiplex_factor\n".
	  "       -u Prune unused interfaces of allocated nodes (-e)(UNIMPLEMENTED)\n".
62
	  "       -d Debug mode prints any problems in the database".
63 64 65 66
	  "       -c Override delay capacity\n".
	  "       -x Output in an RSpec xml format\n".
	  "       -g version With -x, geni version. Must be '0.1', '0.2' or '2'\n".
	  "       -l specifies the location of the type limit file\n" .
67
          "       -1 Print an rspec containing only the node component-name");
68 69 70
        exit(-1);
}

71 72
sub processArgs()
{
73 74 75 76 77 78 79 80 81 82 83 84
    #
    # Parse command arguments. Once we return from getopts, all that should be
    # left are the required arguments.
    #
    my $optlist = "p:e:vrSs:ham:udc:xg:l:1:";
    my %options = ();
    if (! getopts($optlist, \%options)) {
	usage();
    }
    if (@ARGV) {
	usage();
    }
85 86 87
    if (defined($options{"s"})) {
	die("-s (switchtouse) option is not implemented\n");
    }
88 89
    if (defined($options{"x"})) {
	$print_xml = 1;
90
	if (! $libptop_new::PGENISUPPORT) {
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
	    usage();
	}
	my $mode = $options{"g"};
	if (defined($mode)) {
	    if ($mode eq "0.1") {
		$print_ns = $GeniXML::RSPEC_0_1_NS;
	    } elsif ($mode eq "0.2") {
		$print_ns = $GeniXML::RSPEC_0_2_NS;
	    } elsif ($mode eq "2") {
		$print_ns = $GeniXML::RSPEC_2_NS;
	    } else {
		usage();
	    }
	}
    }
    if (defined($options{"l"})) {
	$typelimitfile = $options{"l"};
    }
109 110 111
    if (defined($options{"d"})) {
	$debug = 1;
    }
112
    libptop_new::ProcessArgs(\%options);
113 114 115 116 117
}

sub consultDatabase()
{
    # Bulk lookup on nodes table
118
    libptop_new::LookupNodes();
119

120
    # Bulk lookup of permissions table for project
121
    libptop_new::LookupPermissions();
122 123

    # Bulk lookup of global usage counts for shared nodes
124
    libptop_new::LookupGlobalCounts();
125 126

    # Bulk lookup of node and node_type auxtypes
127
    libptop_new::LookupAuxtypes();
128 129

    # Bulk lookup of node and node_type features
130
    libptop_new::LookupFeatures();
131

132
    # Bulk lookup of osids for features and genimode
133
    libptop_new::LookupOsids();
134

135
    # Bulk lookup of interfaces
136
    libptop_new::LookupInterfaces();
137 138

    # Bulk lookup of wires
139
    libptop_new::LookupLinks();
140

141
    # Process each node adding ptypes and features
142
    foreach my $current (values(%{ libptop_new::Nodes() })) {
143
	if ($current->willPrint()) {
144
	    $current->processTypeFeatures();
145 146 147 148 149 150 151 152 153 154 155
	    $current->processSwitch();
	    $current->processLocal();
	    $current->processWidearea();
	}
    }
}

sub printResults()
{
    my $doc = GeniXML::CreateDocument($print_ns, "rspec");
    my $rspec = $doc->documentElement();
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    $rspec->setNamespace($GeniXML::XSI_NS, "xsi", 0);
    if (! GeniXML::IsVersion0($rspec)) {
	$rspec->setNamespace($GeniXML::EMULAB_NS, "emulab", 0);
	my $ns = $GeniXML::RSPEC_2_NS;
	my $emulabns = $GeniXML::EMULAB_NS;
	my $emulaburl = "http://www.protogeni.net/resources/rspec/ext/emulab/1/ptop_extension.xsd";
	$rspec->setAttributeNS($GeniXML::XSI_NS, "xsi:schemaLocation",
			       "$ns $ns/ad.xsd $emulabns $emulaburl");
	#	if (defined($MAINSITE) && $MAINSITE) {
	#	    Add stitching namespace and schemaLocation
	#	}
    }
    $rspec->setAttribute("type", "advertisement");
    my @times = gmtime(time());
    my $generated = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
			    $times[5] + 1900, $times[4] + 1, $times[3],
			    $times[2], $times[1], $times[0]);
    $rspec->setAttribute("generated", $generated);
    my $expiration = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
			     $times[5] + 1900, $times[4] + 1, $times[3],
			     $times[2], $times[1], $times[0]);
    if (GeniXML::IsVersion0($rspec)) {
	$rspec->setAttribute("valid_until", $expiration);
    } else {
	$rspec->setAttribute("expires", $expiration);
    }
    
183
    foreach my $current (values(%{ libptop_new::Nodes() })) {
184 185 186 187 188 189 190 191
	if ($current->willPrint()) {
	    if ($print_xml) {
		$current->toXML($rspec);
	    } else {
		print $current->toString()."\n";
	    }
	}
    }
192
    foreach my $current (values(%{ libptop_new::Links() })) {
193 194 195 196 197 198 199 200
	if ($current->willPrint()) {
	    if ($print_xml) {
		$current->toXML($rspec);
	    } else {
		print $current->toString()."\n";
	    }
	}
    }
201
    printTypeLimits($rspec);
202 203 204 205
    if ($print_xml) {
	print GeniXML::Serialize($rspec, 1)."\n";
    }
}
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230

sub printTypeLimits($)
{
    my ($rspec) = @_;
    if (defined($typelimitfile)) {
	open(TYPELIMIT, "<$typelimitfile") or 
	    die("Count not open type limit file $typelimitfile\n");
	my @typelimits = <TYPELIMIT>;
	close(TYPELIMIT);

	foreach my $line (@typelimits) { 
	    chomp($line);
	    my ($typeclass, $count) = split(" ", $line);
	    
	    if ($print_xml && ! GeniXML::IsVersion0($rspec)) {
		my $limit = GeniXML::AddElement("set_type_limit", $rspec,
						$GeniXML::EMULAB_NS);
		GeniXML::SetText("typeclass", $limit, $typeclass);
		GeniXML::SetText("count", $limit, $count);
	    } else {
		print "set-type-limit $typeclass $count\n";
	    }
	}
    }
}