Commit bc8d9766 authored by Shah Rinku's avatar Shah Rinku

Adding preliminary modules for dispatching at NIC

parent 128b235b
{"id":"192.168.0.106","master_node":"192.168.0.105"}
\ No newline at end of file
{"id":"10.129.2.201","master_node":"192.168.0.105"}
\ No newline at end of file
......@@ -97,19 +97,32 @@ function runContainer(metadata) {
else {
let process = null;
if (constants.network.use_bridge)
process = spawn('docker', ["run", "--rm", `--network=${constants.network.network_bridge}`, "-p", `${port}:${port}`,
"--name", resource_id, registry_url + imageName,
process = spawn('docker', ["create", "--rm", `--network=${constants.network.network_bridge}`, "-p", `${port}:${port}`,
"-p", `${port}:${port}/udp`, "--name", resource_id, registry_url + imageName,
resource_id, imageName, port, "container", constants.network.internal.kafka_host]);
else
process = spawn('docker', ["run", "--rm", "-p", `${port}:${port}`,
"--name", resource_id, registry_url + imageName,
process = spawn('docker', ["create", "--rm", "-p", `${port}:${port}`,
"-p", `${port}:${port}/udp`, "--name", resource_id, registry_url + imageName,
resource_id, imageName, port, "container", constants.network.internal.kafka_host]);
let result = "";
// timeStart = Date.now()
process.stdout.on('data', (data) => {
logger.info(`stdout: ${data}`);
let timeDifference = Math.ceil((Date.now() - timeStart))
logger.info("container run time taken: ", timeDifference);
let add_network = spawn('docker', ['network', 'connect', 'pub_net', resource_id])
let _ = spawn('docker', ['start', resource_id])
_.on('data', (data) => {
console.log("container started", data);
})
// add_network.stderr.on('data', (data) => {
// // console.log("network add error", data);
// })
add_network.on('close', (code) => {
logger.info("Ran command");
})
result += data;
resolve(resource_id);
});
......@@ -129,21 +142,43 @@ function runContainer(metadata) {
} else {
logger.info("container starting at port", port);
let process = null;
/**
* create docker on the default bridge
*/
if (constants.network.use_bridge)
process = spawn('docker', ["run", "--rm", `--network=${constants.network.network_bridge}`,
"-p", `${port}:${port}`, "--name", resource_id,
process = spawn('docker', ["create", "--rm", `--network=${constants.network.network_bridge}`,
"-p", `${port}:${port}`, "-p", `${port}:${port}/udp`, "--name", resource_id,
registry_url + imageName, resource_id, imageName, port, "container", constants.network.internal.kafka_host]);
else
process = spawn('docker', ["run", "--rm",
"-p", `${port}:${port}`, "--name", resource_id,
process = spawn('docker', ["create",
"-p", `${port}:${port}`, "-p", `${port}:${port}/udp`, "--name", resource_id,
registry_url + imageName, resource_id, imageName, port, "container", constants.network.internal.kafka_host]);
let result = "";
// timeStart = Date.now()
process.stdout.on('data', (data) => {
logger.info(`stdout: ${data}`);
logger.info(`stdout: ${data.toString()}`);
let timeDifference = Math.ceil((Date.now() - timeStart))
logger.info("container run time taken: ", timeDifference);
resolve(resource_id);
/**
* attach smartnic interface
*/
let add_network = spawn('docker', ['network', 'connect', 'pub_net', resource_id])
let _ = spawn('docker', ['start', resource_id])
_.stdout.on('data', (data) => {
logger.info(data.toString())
resolve(resource_id);
})
_.stderr.on('data', (data) => {
logger.info(data.toString())
})
_.on('close', (data) => {
logger.info("exit exit")
logger.info(data.toString())
})
});
process.stderr.on('data', (data) => {
......
......@@ -21,7 +21,7 @@ function updateConfig() {
data = data.substr(0, data.indexOf("\n")).trim()
data = data.split(' ')
file.id = data[data.length - 3]
file.id = data[data.length - 1]
fs.writeFileSync('./config.json', JSON.stringify(file));
console.log("Updated Config file");
}
......@@ -135,4 +135,4 @@ const logger = winston.createLogger({
module.exports = {
download, makeid, updateConfig, makeTopic, returnPort, logger
}
\ No newline at end of file
}
......@@ -295,6 +295,15 @@ function postDeploy(message) {
return;
}
/**
* IP changes in case MACVLAN is used to connect worker endpoints
*/
if (resourceMap.has(message.resource_id)) {
let resource = resourceMap.get(message.resource_id)
resource.node_id = message.node_id.trim()
}
if (functionToResource.has(id)) {
let resourceHeap = functionToResource.get(id)
heap.push(resourceHeap, {
......@@ -621,6 +630,6 @@ async function speculative_deployment(req, runtime) {
}
}
setInterval(libSupport.metrics.broadcastMetrics, 5000)
setInterval(autoscalar, 1000);
// setInterval(autoscalar, 1000);
setInterval(dispatch, 1000);
app.listen(port, () => logger.info(`Server listening on port ${port}!`))
\ No newline at end of file
jspack @ 4753fb1a
Subproject commit 4753fb1a8deb8e2871d34dda049cb01958137f6b
......@@ -75,7 +75,7 @@ function generateExecutor(functionPath, functionHash) {
* @param {JSON} res Object to use to return the response to the user
*/
async function reverseProxy(req, res) {
if (req.headers['x-chain-type'] !== 'explicit')
if (req.headers['x-chain-type'] !== 'explicit' && req.body.type === "tcp")
branchChainPredictor(req)
let runtime = req.body.runtime
let id = req.params.id + runtime
......@@ -140,7 +140,7 @@ async function reverseProxy(req, res) {
catch (err) {
res.json(err.message).status(err.statusCode)
forwardTo.open_request_count -= 1
heap.heapify(functionHeap, compare)
heap.heapify(functionHeap, compare)
logger.error("error" + err)
}
} else if (req.body.type === "udp") {
......@@ -148,11 +148,11 @@ async function reverseProxy(req, res) {
req.body.request_id = request_id
// res.request_id = request_id
requestFlightQueue.set(request_id, res)
let payload = req.body.payload
let payload = req.body
payload.request_id = request_id
payload = JSON.stringify(payload)
udpProxy.send(payload, 0, payload.length, resource.port, resource.node_id, function (err, bytes) {
logger.info("forwarded request via UDP")
// logger.info(`forwarded request via UDP, IP 192.168.2.5 Port ${resource.port}`)
})
}
}
......
This diff is collapsed.
This diff is collapsed.
#
# Copyright (C) 2015-2017, Netronome Systems, Inc. All rights reserved.
#
import os, sys, struct, pprint, threading
from urlparse import urlparse
from contextlib import contextmanager
from RTERPCInterface import *
class RTEInterfaceConnection(object):
def __init__(self):
self.transport = None
self.Design = None
self.Counters = None
self.Tables = None
self.ParserValueSets = None
self.Registers = None
self.Meters = None
self.TrafficClass = None
self.Digests = None
self.Multicast = None
self.DebugCtl = None
self.System = None
self._DoConnect = None
self._DoDisconnect = None
def Connect(self, rpc, host, port, device_id=0, use_zlib=True, serialise_api=False):
if rpc == 'thrift':
from RTEThriftInterface import (Design, Counters, Tables, ParserValueSets,
Registers, Meters, TrafficClass, Digests, Multicast, DebugCtl, System)
from RTEThriftInterface import RteReturnHandler, DoConnect, DoDisconnect
global P4CounterType, RegisterType
from RTEThriftInterface import P4CounterType, RegisterType
elif rpc == 'grpc':
from RTEGRPCInterface import (Design, Counters, Tables, ParserValueSets,
Registers, Meters, TrafficClass, Digests, Multicast, DebugCtl, System)
from RTEGRPCInterface import (RteReturnHandler, DoConnect, DoDisconnect)
else:
raise Exception, 'unsupported rpc: %s'%rpc
DoConnect(self, host, port, device_id, use_zlib, serialise_api)
self.Design = Design(self)
self.Counters = Counters(self)
self.Tables = Tables(self)
self.ParserValueSets = ParserValueSets(self)
self.Registers = Registers(self)
self.Meters = Meters(self)
self.TrafficClass = TrafficClass(self)
self.Digests = Digests(self)
self.Multicast = Multicast(self)
self.DebugCtl = DebugCtl(self)
self.System = System(self)
self._DoConnect = DoConnect
self._DoDisconnect = DoDisconnect
status = self.Design.LoadStatus()
if rpc == 'grpc' and status['is_loaded']:
self.Design.RefreshP4Schema()
def Disconnect(self):
if self._DoDisconnect is not None:
self._DoDisconnect(self)
@contextmanager
def ConnectCtx(self, rpc, host, port, device_id=0, use_zlib=True, serialise_api=False):
try:
self.Connect(rpc, host, port, device_id, use_zlib, serialise_api)
yield self
finally:
self.Disconnect()
def Shutdown(self):
self.System.Shutdown()
self.Disconnect()
RTEInterface = RTEInterfaceConnection()
#
# Copyright (C) 2017, Netronome Systems, Inc. All rights reserved.
#
import os, sys, struct, pprint, threading
from urlparse import urlparse
from contextlib import contextmanager
class RTEError(Exception): pass
class RTECommError(RTEError): pass
class RTERPCNotImplemented(RTEError): pass
class RTEReturnError(RTEError): pass
RTE_RETURN_CODES = [
'SUCCESS',
'ERROR', # error reason string provided
'ARGINVALID', # invalid argument
'IOERROR', # platform IO error
'MEMORYERROR', # memory allocation error
'FILEIOERROR', # file IO error
'NOTLOADED', # firmware not loaded
'HWINCOMPATIBLE', # platform doesn't support operation
]
# XXX a hack for now, but these should be shared definitions for thrift/grpc
class LogLevel(object):
UNKNOWN = 0
DISABLE = 1
FATAL = 2
ERROR = 3
WARN = 4
INFO = 5
DEBUG = 6
EXTRA = 7
HEAVY = 8
class P4CounterType(object):
Global = 'P4CounterType.Global'
Direct = 'P4CounterType.Direct'
Static = 'P4CounterType.Static'
class P4CounterClass(object):
Invalid = 'P4CounterClass.Invalid'
Unspecified = 'P4CounterClass.Unspecified'
Packets = 'P4CounterClass.Packets'
Bytes = 'P4CounterClass.Bytes'
Both = 'P4CounterClass.Both'
class RegisterType(object):
Global = 'RegisterType.Global'
Direct = 'RegisterType.Direct'
Static = 'RegisterType.Static'
class MeterType(object):
Invalid = 'MeterType.Invalid'
Global = 'MeterType.Global'
Direct = 'MeterType.Direct'
Static = 'MeterType.Static'
class MeterClass(object):
Invalid = 'MeterClass.Invalid'
Unspecified = 'MeterClass.Unspecified'
Packets = 'MeterClass.Packets'
Bytes = 'MeterClass.Bytes'
class MatchType(object):
Unspecified = 'MatchType.Unspecified'
Valid = 'MatchType.Valid'
Exact = 'MatchType.Exact'
LPM = 'MatchType.LPM'
Ternary = 'MatchType.Ternary'
Range = 'MatchType.Range'
#class RegisterFieldDesc(object):
#class RegisterType(object):
def REV_MAP(m):
res = {}
for k, v in m.items():
res['v'] = k
return res
class NullCtx():
def __enter__(*args): pass
def __exit__(*exc_info): pass
class RTEModule(object):
def __init__(self, rte):
self.rte = rte
class DesignBase(RTEModule):
def Load(self, elf_fw, pif_design, pif_config):
raise RTERPCNotImplemented
def Unload(self):
raise RTERPCNotImplemented
def ConfigReload(self, pif_config):
raise RTERPCNotImplemented
def LoadStatus(self):
raise RTERPCNotImplemented
class CountersBase(RTEModule):
def ResolveToCounterId(self, counter):
if isinstance(counter, (int, long)):
counter_id = counter
elif isinstance(counter, basestring):
counter_id = self.GetP4CounterByName(counter)['id']
elif isinstance(counter, dict):
counter_id = counter['id']
else:
raise RTEError, "Unexpected counter parameter type %s"%type(counter)
def GetP4Counters(self):
return [(counter, self.GetP4Counter(counter)) for counter in self.ListP4Counters()]
def GetP4CounterByName(self, counter_name):
for counter in self.ListP4Counters():
if counter['name'] == counter_name:
return counter
raise RTEError, "Counter '%s' not found"%counter_name
def ExtractRteValue(self, rv):
raise RTERPCNotImplemented
def ListP4Counters(self):
raise RTERPCNotImplemented
def GetP4Counter(self, counter):
raise RTERPCNotImplemented
def ClearP4Counter(self, counter):
raise RTERPCNotImplemented
def ClearAllP4Counters(self):
raise RTERPCNotImplemented
def GetSystemCounters(self):
raise RTERPCNotImplemented
def ClearAllSysCounters(self):
raise RTERPCNotImplemented
class TablesBase(RTEModule):
def GetTableByName(self, table_name):
for table in self.List():
if table['tbl_name'] == table_name:
return table
raise RTEError, "Table '%s' not found"%table_name
def ResolveToTableId(self, tbl_id):
if isinstance(tbl_id, int):
return tbl_id
elif isinstance(tbl_id, basestring):
return self.GetTableByName(tbl_id)['tbl_id']
else:
raise RTEError, 'Unsupported table name type: %s'%type(tbl_id)
def AddRule(self, tbl_id, rule_name, default_rule, match, actions, priority = None, timeout = None):
raise RTERPCNotImplemented
def EditRule(self, tbl_id, rule_name, default_rule, match, actions, priority = None, timeout = None):
raise RTERPCNotImplemented
def DeleteRule(self, tbl_id, rule_name, default_rule, match, actions):
raise RTERPCNotImplemented
def List(self):
raise RTERPCNotImplemented
def ListRules(self, tbl_id):
raise RTERPCNotImplemented
def GetVersion(self):
raise RTERPCNotImplemented
class RegistersBase(RTEModule):
def GetRegisterByName(self, register_name):
for reg in self.List():
if reg['name'] == register_name:
return reg
raise RTEError, "Register '%s' not found"%register_name
def List(self):
raise RTERPCNotImplemented
def ResolveToRegisterArrayArg(self, register, index, count):
raise RTERPCNotImplemented
def Get(self, register, index=0, count=1):
raise RTERPCNotImplemented
def Clear(self, register, index=0, count=1):
raise RTERPCNotImplemented
def Set(self, register, values, index=0, count=1):
raise RTERPCNotImplemented
def SetField(self, register, field_id, value, index=0, count=1):
raise RTERPCNotImplemented
class TrafficClassBase(RTEModule):
def Get(self, port_id):
raise RTERPCNotImplemented
def Set(self, port_id, cfgs):
raise RTERPCNotImplemented
def Commit(self, port_id):
raise RTERPCNotImplemented
class MetersBase(RTEModule):
def List(self):
raise RTERPCNotImplemented
def GetConfig(self, meter_id):
raise RTERPCNotImplemented
def SetConfig(self, meter_id, configs):
raise RTERPCNotImplemented
class DigestsBase(RTEModule):
def List(self):
raise RTERPCNotImplemented
def Register(self, digest_id):
raise RTERPCNotImplemented
def Deregister(self, digest_regid):
raise RTERPCNotImplemented
def Get(self, digest_handle):
raise RTERPCNotImplemented
class MulticastBase(RTEModule):
def List(self):
raise RTERPCNotImplemented
def SetConfig(self, group_id, ports):
raise RTERPCNotImplemented
class SystemBase(RTEModule):
def Shutdown(self):
raise RTERPCNotImplemented
def Ping(self):
raise RTERPCNotImplemented
def Echo(self, echo_msg):
raise RTERPCNotImplemented
def GetVersion(self):
raise RTERPCNotImplemented
def GetLogLevel(self):
raise RTERPCNotImplemented
def SetLogLevel(self, level):
raise RTERPCNotImplemented
def GetPortInfo(self):
raise RTERPCNotImplemented
class DebugCtlBase(RTEModule):
def Execute(self, debug_id, debug_data):
raise RTERPCNotImplemented
def SetRuleBreakpoint(self, table_name, rule_name, enable):
self.Execute('netro_rule_bpt', 'table %s rule %s enabled %s'%(table_name, rule_name, int(enable)))
def GetRuleBreakpoint(self, table_name, rule_name):
res = self.Execute('netro_rule_bpt', 'table %s rule %s'%(table_name, rule_name))
name, val = res.split(None, 1)
assert name=='enabled'
return bool(int(val))
def SetMacConfig(self, nbi0_config, nbi1_config):
for (conf_id, conf_json) in (('nbi_mac8_json', nbi0_config),
('nbi_mac9_json', nbi1_config)):
if conf_json:
with open(conf_json, "rb") as f:
self.Execute(conf_id, f.read())
class ParserValueSetsBase(RTEModule):
def List(self):
raise RTERPCNotImplemented
def Clear(self, pvs_id):
raise RTERPCNotImplemented
def Add(self, pvs_id, pvs_entries):
raise RTERPCNotImplemented
def Retrieve(self, pvs_id):
raise RTERPCNotImplemented
This diff is collapsed.
#!/bin/bash -x
sudo ifconfig vf0_0 192.168.2.2/24 up
sudo ifconfig vf0_1 192.168.2.3/24 up
# create a MAC VLAN for docker attached to vf0_1
echo "y" | docker system prune
docker network create -d macvlan --subnet=192.168.2.0/24 --aux-address="vf0_0=192.168.2.2" --aux-address="vf0_1=192.168.2.3" -o parent=vf0_1 pub_net
# move vf0_0 into its own namespace
# sudo ip netns exec ns_server ip link set vf0_0 netns 1
# sudo ip netns delete ns_server
# sudo ip netns add ns_server
# sudo ip link set vf0_0 netns ns_server
# sudo ip netns exec ns_server ip addr add dev vf0_0 192.168.2.2/24
# sudo ip netns exec ns_server ip link set dev vf0_0 up
# sudo ip netns exec ns_server arp -s 192.168.2.3 00:22:22:22:22:22 -i vf0_0
# sudo ip netns exec ns_server arp -s 192.168.2.4 00:33:33:33:33:33 -i vf0_0
# sudo arp -s 192.168.2.2 00:11:11:11:11:11 -i vf0_1
# sudo arp -s 192.168.2.4 00:33:33:33:33:33 -i vf0_1
\ No newline at end of file
#! /bin/bash -x
compile_flag=0
location=$(pwd)
while getopts 'c' flag; do
case "${flag}" in
c) compile_flag=1 ;;
esac
done
if [[ $compile_flag -eq 1 ]]
then
# compile the nfp code
sudo /opt/netronome/p4/bin/nfp4build -o ./p4src/echo.nffw -p ./p4src/out -4 ./p4src/echo.p4 -l lithium --nfp4c_p4_version 16 --nfp4c_p4_compiler p4c-nfp -c ./p4src/prime.c
fi
# move to p4 bin
cd /opt/netronome/p4/bin/
# #offload
sudo ./rtecli design-load -f $location/p4src/echo.nffw -c $location/p4src/echo.p4cfg -p $location/p4src/out/pif_design.json
# returning back to base
cd $location
\ No newline at end of file
#!/usr/bin/env python
#
# based on the RunTimeEnvironment-remote example
# that comes generated by thrift
#
import argparse
import struct
import sys
import pprint
import collections
import time
sys.path.append('../../out/gen_thrift/py')
from urlparse import urlparse
from thrift.transport import TTransport
from thrift.transport import TZlibTransport
from thrift.transport import TSocket
#from thrift.transport import TSSLSocket
from thrift.transport import THttpClient
from thrift.protocol import TBinaryProtocol
from sdk6_rte import RunTimeEnvironment
from sdk6_rte.ttypes import *
if __name__ == '__main__':
#
# Argument handling
#
parser = argparse.ArgumentParser()
parser.add_argument('-s','--server',
dest='rpc_server', default='localhost',
type=str,
help="Thrift RPC host (DEFAULT: localhost)")
parser.add_argument('-p','--port',
dest='rpc_port', default='20206',
type=str,
help="Thrift RPC port (DEFAULT: 20206)")
parser.set_defaults()
args = parser.parse_args()
use_zlib = 1
host = args.rpc_server
port = int(args.rpc_port)
socket = TSocket.TSocket(host, port)
transport = TTransport.TBufferedTransport(socket)
if use_zlib:
transport = TZlibTransport.TZlibTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)