Commit 382962e0 authored by Leigh Stoller's avatar Leigh Stoller

Check RF monitor support and CM support for spectrum requests.

parent 405ada0e
......@@ -37,7 +37,8 @@ BIN_SCRIPTS = manage_profile manage_instance manage_dataset \
create_slivers searchip
SBIN_SCRIPTS = apt_daemon aptevent_daemon portal_xmlrpc apt_checkup \
portal_monitor apt_scheduler portal_resources \
manage_licenses manage_aggregate powder_shutdown
manage_licenses manage_aggregate powder_shutdown \
rfmonitor_daemon
LIB_SCRIPTS = APT_Profile.pm APT_Instance.pm APT_Dataset.pm APT_Geni.pm \
APT_Aggregate.pm APT_Utility.pm APT_Rspec.pm
WEB_BIN_SCRIPTS = webmanage_profile webmanage_instance webmanage_dataset \
......
This diff is collapsed.
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
# Copyright (c) 2000-2019 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -693,6 +693,7 @@ sub TBDB_PHYSICAL_NODE_TABLES() {
'interfaces' => [ 'node_id' ],
'interface_settings' => [ 'node_id' ],
'interface_state' => [ 'node_id' ],
'interfaces_rf_limit' => [ 'node_id' ],
'last_reservation' => [ 'node_id' ],
'linkdelays' => [ 'node_id' ],
'location_info' => [ 'node_id' ],
......@@ -705,6 +706,7 @@ sub TBDB_PHYSICAL_NODE_TABLES() {
'node_idlestats' => [ 'node_id' ],
'node_status' => [ 'node_id' ],
'node_rusage' => [ 'node_id' ],
'node_rf_reports' => [ 'node_id' ],
'nodeipportnum' => [ 'node_id' ],
'nodes' => [ 'node_id', 'phys_nodeid' ],
'nodeuidlastlogin' => [ 'node_id' ],
......
......@@ -3759,6 +3759,12 @@ sub RemovePhysicalState($;$)
"where ($clause) and ".
" role='" . TBDB_IFACEROLE_EXPERIMENT() . "' ")
or $errors++;
# RF interfaces (also cleaned in nfree).
DBQueryWarn("DELETE FROM interfaces_rf_limit WHERE $clause")
or $errors++;
DBQueryWarn("delete from node_rf_reports where $clause")
or $errors++;
}
foreach my $table (keys(%physicalTables)) {
......
......@@ -4575,5 +4575,50 @@ sub NeedsAdminMFS($)
return 0;
}
#
# Spectrum stuff.
#
sub AddSpectrum($$$)
{
my ($self, $spectrum, $iface) = @_;
my $node_id = $self->node_id();
my @ifaces = ();
require EmulabConstants;
if (defined($iface)) {
@ifaces = ($iface);
}
else {
if (Interface->LookupAll($self, \@ifaces)) {
return -1;
}
}
foreach $iface (@ifaces) {
my $iface_id = $iface->iface();
next
if ($iface->role() != EmulabConstants::TBDB_IFACEROLE_EXPERIMENT());
# Check to see if this is an OTA interface.
my $ota;
next
if (! ($iface->TypeCapability("overtheair", \$ota) == 0 && $ota));
foreach my $request (@{$spectrum}) {
my $frequency_low = DBQuoteSpecial($request->{"frequency_low"});
my $frequency_high = DBQuoteSpecial($request->{"frequency_high"});
my $power = DBQuoteSpecial($request->{"power"});
return -1
if (!DBQueryWarn("insert into interfaces_rf_limit set ".
" node_id='$node_id', iface='$iface_id', ".
" freq_low=$frequency_low, ".
" freq_high=$frequency_high, ".
" power=$power"));
}
}
return 0;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
# Copyright (c) 2000-2017, 2019 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -551,6 +551,12 @@ foreach my $node (@freed_nodes) {
DBQueryWarn("delete from interface_settings where node_id='$node_id'")
or $error++;
# Clean the RF limit/reporting tables.
DBQueryWarn("delete from interfaces_rf_limit where node_id='$node_id'")
or $error++;
DBQueryWarn("delete from node_rf_reports where node_id='$node_id'")
or $error++;
# If it's a robot, we need to reset its physical location.
my $result =
DBQueryFatal("select building,floor,loc_x,loc_y,orientation ".
......
......@@ -936,6 +936,19 @@ sub GetTicketAuxAux($)
$virtexperiment->delay_osname($delayname);
}
#
# Check global spectrum request
#
my $spectrum = GeniXML::GetSpectrum($rspec);
if (@$spectrum) {
print STDERR "Global spectrum:\n";
print STDERR Dumper($spectrum);
my $response = CheckSpectrum($spectrum);
return $response
if (GeniResponse::IsError($response));
}
#
# Add global vtypes.
#
......@@ -1217,6 +1230,19 @@ sub GetTicketAuxAux($)
my $xensettings;
my $dockersettings;
my $fwsettings;
#
# Check spectrum request
#
my $spectrum = GeniXML::GetSpectrum($ref);
if (@$spectrum) {
print STDERR "Node $node_nickname spectrum:\n";
print STDERR Dumper($spectrum);
my $response = CheckSpectrum($spectrum);
goto bad
if (GeniResponse::IsError($response));
}
# Always populate iface2node mapping, even if we let the node
# pass through.
......@@ -1231,6 +1257,27 @@ sub GetTicketAuxAux($)
goto bad;
}
$iface2node{$virtual_id} = $node_nickname;
#
# Check spectrum request
#
my $spectrum = GeniXML::GetSpectrum($linkref);
if (@$spectrum) {
my $component_id = GeniXML::GetNodeId($linkref);
if (!defined($component_id)) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Must supply component_id (interface) for ".
"spectrum on $virtual_id");
goto bad;
}
print STDERR "Interface $virtual_id:$component_id spectrum:\n";
print STDERR Dumper($spectrum);
my $response = CheckSpectrum($spectrum);
goto bad
if (GeniResponse::IsError($response));
}
}
# Let remote nodes pass through.
......@@ -2786,7 +2833,9 @@ sub GetTicketAuxAux($)
#
# Look for shared and tagging attributes for the link.
#
if (my $shared_vlan = GeniXML::GetSharedLanName($linkref)) {
my $shared_vlan;
if ($shared_vlan = GeniXML::GetSharedLanName($linkref)) {
if ($shared_vlan !~ /^[-\w]*$/) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
......@@ -2832,7 +2881,7 @@ sub GetTicketAuxAux($)
$isshared = 1;
$encap = "vlan";
}
elsif (my $shared_vlan = GeniXML::CreateSharedLan($linkref)) {
elsif ($shared_vlan = GeniXML::CreateSharedLan($linkref)) {
if ($shared_vlan !~ /^[-\w]*$/) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
......@@ -4729,8 +4778,10 @@ sub SliverWorkAux($)
}
}
my %phys2nickname = ();
# global spectrum for below.
my $global_spectrum = GeniXML::GetSpectrum($rspec);
my %phys2nickname = ();
#
# Make sure all nodes requested are allocated.
#
......@@ -5159,6 +5210,49 @@ sub SliverWorkAux($)
}
}
#
# Per-Interface Spectrum
#
foreach my $ifaceref (GeniXML::FindNodes("n:interface",
$ref)->get_nodelist()) {
my $spectrum = GeniXML::GetSpectrum($ifaceref);
if (@$spectrum) {
my $component_id = GeniXML::GetNodeId($ifaceref);
my $interface = Interface->LookupByIface($node, $component_id);
if (!defined($interface) ) {
$message = "Undefined interface $component_id for ".
"spectrum on $virtual_id";
goto bad;
}
if ($node->AddSpectrum($spectrum, $interface)) {
$message = "Could not add interface spectrum to ".
"$virtual_id:$component_id";
goto bad;
}
}
}
#
# Per-node spectrum.
#
my $spectrum = GeniXML::GetSpectrum($ref);
if (@$spectrum) {
if ($node->AddSpectrum($spectrum)) {
$message = "Could not add spectrum to $virtual_id";
goto bad;
}
}
#
# And the global spectrum
#
if (@$global_spectrum) {
if ($node->AddSpectrum($global_spectrum)) {
$message = "Could not add global spectrum to $virtual_id";
goto bad;
}
}
my $node_manifest = $sliver->AnnotateManifest();
if (! defined($node_manifest)) {
$message = "Could not annotate sliver for $virtual_id";
......@@ -5529,6 +5623,7 @@ sub SliverWorkAux($)
goto bad;
}
}
# Initial update of the manifest.
$ifaceref = $sliver->AnnotateManifest($ifaceref);
my $outref;
......@@ -9255,5 +9350,60 @@ sub CheckForDeprecatedImages($$)
return 0;
}
#
# Do some sanity checking on spectrum list.
#
# Initial limits to apply to all requests, eventually these will come from
# the database. Express these as a set of ranges with associated max power,
# which for now is the same for all frequencies. In MHZ and dBm.
#
my @TXlimits = (
# freq_low,freq_high,power
[902, 928, 15],
[2400, 2500, 15],
[5725, 5875, 15],
);
sub CheckSpectrum($)
{
my ($spectrum) = @_;
foreach my $request (@{$spectrum}) {
my $frequency_low = $request->{"frequency_low"};
my $frequency_high = $request->{"frequency_high"};
my $power = $request->{"power"};
if (!defined($frequency_high) ||
!defined($frequency_low) ||
!defined($power) ||
$frequency_high !~ /^[\d\.]+$/ ||
$frequency_low !~ /^[\d\.]+$/ ||
$power !~ /^[-\d\.]+$/ ||
$frequency_low > $frequency_high ||
$frequency_low < 0) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid spectrum request");
}
# Check for out of range,power.
my $allowed = 0;
foreach my $ref (@TXlimits) {
my ($low,$high,$pmax) = @{$ref};
if ($frequency_low >= $low &&
$frequency_high <= $high &&
$power <= $pmax) {
$allowed = 1;
last;
}
}
if (!$allowed) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Spectrum range request is out of permitted range: ".
"$frequency_low,$frequency_high,$power");
}
}
return 0;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -1944,5 +1944,20 @@ sub GetRepositories($)
return $result;
}
sub GetSpectrum($)
{
my ($ref) = @_;
my @result = ();
foreach my $element (FindNodesNS("n:spectrum", $ref,
$EMULAB_NS)->get_nodelist()) {
push(@result, {
"frequency_low" => GetText("frequency_low", $element),
"frequency_high" => GetText("frequency_high", $element),
"power" => GetText("power", $element)});
}
return \@result;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -2898,8 +2898,9 @@ DROP TABLE IF EXISTS `node_rf_reports`;
CREATE TABLE `node_rf_reports` (
`node_id` varchar(32) NOT NULL DEFAULT '',
`tstamp` datetime NOT NULL default '0000-00-00 00:00:00',
`which` enum('system','user') default 'user',
`report` text NOT NULL,
PRIMARY KEY (`node_id`)
PRIMARY KEY (`node_id`,`which`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
......
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("node_rf_reports", "which")) {
DBQueryFatal("drop table node_rf_reports");
}
if (!DBTableExists("node_rf_reports")) {
DBQueryFatal("CREATE TABLE `node_rf_reports` ( ".
" `node_id` varchar(32) NOT NULL DEFAULT '', ".
" `tstamp` datetime NOT NULL default '0000-00-00 00:00:00',".
" `which` enum('system','user') default 'user', ".
" `report` text NOT NULL, ".
" PRIMARY KEY (`node_id`,`which`) ".
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
}
return 0;
}
1;
# Local Variables:
# mode:perl
# End:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment