ptopgen_new.in 6.3 KB
Newer Older
1 2 3 4
#!/usr/bin/perl -w

#
# EMULAB-COPYRIGHT
5
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
6 7 8 9 10 11 12
# 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
    #
    # Parse command arguments. Once we return from getopts, all that should be
    # left are the required arguments.
    #
77
    my $optlist = "p:e:vrSs:ham:udc:xg:l:1:C";
78 79 80 81 82 83 84
    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
	    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;
101 102
	    } elsif ($mode eq "3") {
		$print_ns = $GeniXML::RSPEC_3_NS;
103 104 105 106 107 108 109 110
	    } else {
		usage();
	    }
	}
    }
    if (defined($options{"l"})) {
	$typelimitfile = $options{"l"};
    }
111 112 113
    if (defined($options{"d"})) {
	$debug = 1;
    }
114
    libptop_new::ProcessArgs(\%options);
115 116 117 118 119
}

sub consultDatabase()
{
    # Bulk lookup on nodes table
120
    libptop_new::LookupNodes();
121

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

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

    # Bulk lookup of node and node_type auxtypes
129
    libptop_new::LookupAuxtypes();
130 131

    # Bulk lookup of node and node_type features
132
    libptop_new::LookupFeatures();
133

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

137
    # Bulk lookup of interfaces
138
    libptop_new::LookupInterfaces();
139 140

    # Bulk lookup of wires
141
    libptop_new::LookupLinks();
142

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

    libptop_new::AddFakeNodes();
154 155 156 157 158 159
}

sub printResults()
{
    my $doc = GeniXML::CreateDocument($print_ns, "rspec");
    my $rspec = $doc->documentElement();
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    $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);
    }
    
187
    foreach my $current (values(%{ libptop_new::Nodes() })) {
188 189 190 191 192 193 194 195
	if ($current->willPrint()) {
	    if ($print_xml) {
		$current->toXML($rspec);
	    } else {
		print $current->toString()."\n";
	    }
	}
    }
196
    foreach my $current (values(%{ libptop_new::Links() })) {
197 198 199 200 201 202 203 204
	if ($current->willPrint()) {
	    if ($print_xml) {
		$current->toXML($rspec);
	    } else {
		print $current->toString()."\n";
	    }
	}
    }
205
    printTypeLimits($rspec);
206 207 208 209
    if ($print_xml) {
	print GeniXML::Serialize($rspec, 1)."\n";
    }
}
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

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";
	    }
	}
    }
}