Merge branch 'develop' into FRR-patch-1

This commit is contained in:
bharnden 2019-04-24 22:56:24 -07:00 committed by GitHub
commit d584bbbcb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 3645 additions and 151 deletions

View file

@ -389,7 +389,7 @@ class CoreBroker(object):
sid = self.session_id_master
if sid is None:
# this is the master session
sid = self.session.session_id
sid = self.session.id
key = (sid << 16) ^ hash(n1num) ^ (hash(n2num) << 8)
return key & 0xFFFFFFFF
@ -697,7 +697,7 @@ class CoreBroker(object):
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.DATA_TYPES.value, (ConfigDataTypes.STRING.value,))
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.VALUES.value,
"%s:%s:%s" % (server.name, server.host, server.port))
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.SESSION.value, "%s" % self.session.session_id)
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.SESSION.value, "%s" % self.session.id)
msg = coreapi.CoreConfMessage.pack(0, tlvdata)
server.sock.send(msg)
@ -973,7 +973,7 @@ class CoreBroker(object):
filename = os.path.join(self.session.session_dir, "servers")
master = self.session_id_master
if master is None:
master = self.session.session_id
master = self.session.id
try:
with open(filename, "w") as f:
f.write("master=%s\n" % master)

View file

@ -10,9 +10,9 @@ FRR_STATE_DIR = "@CORE_STATE_DIR@/run/frr"
def which(command):
for path in os.environ["PATH"].split(os.pathsep):
command_path = os.path.join(path, command)
if os.path.isfile(command_path) and os.access(command_path, os.X_OK):
return command_path
command_path = os.path.join(path, command)
if os.path.isfile(command_path) and os.access(command_path, os.X_OK):
return command_path
VNODED_BIN = which("vnoded")

View file

@ -57,7 +57,6 @@ class CoreHandler(SocketServer.BaseRequestHandler):
:param request: request object
:param str client_address: client address
:param CoreServer server: core server instance
:return:
"""
self.done = False
self.message_handlers = {
@ -140,7 +139,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
self.session.broker.session_clients.remove(self)
if not self.session.broker.session_clients and not self.session.is_active():
logging.info("no session clients left and not active, initiating shutdown")
self.coreemu.delete_session(self.session.session_id)
self.coreemu.delete_session(self.session.id)
return SocketServer.BaseRequestHandler.finish(self)
@ -160,9 +159,9 @@ class CoreHandler(SocketServer.BaseRequestHandler):
num_sessions = 0
with self._sessions_lock:
for session_id, session in self.coreemu.sessions.iteritems():
for _id, session in self.coreemu.sessions.iteritems():
num_sessions += 1
id_list.append(str(session_id))
id_list.append(str(_id))
name = session.name
if not name:
@ -320,13 +319,16 @@ class CoreHandler(SocketServer.BaseRequestHandler):
:return: nothing
"""
logging.debug("handling broadcast link: %s", link_data)
per = ""
if link_data.per is not None:
per = str(link_data.per)
tlv_data = structutils.pack_values(coreapi.CoreLinkTlv, [
(LinkTlvs.N1_NUMBER, link_data.node1_id),
(LinkTlvs.N2_NUMBER, link_data.node2_id),
(LinkTlvs.DELAY, link_data.delay),
(LinkTlvs.BANDWIDTH, link_data.bandwidth),
(LinkTlvs.PER, link_data.per),
(LinkTlvs.PER, per),
(LinkTlvs.DUP, link_data.dup),
(LinkTlvs.JITTER, link_data.jitter),
(LinkTlvs.MER, link_data.mer),
@ -369,7 +371,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
:return: register message data
"""
logging.info("GUI has connected to session %d at %s", self.session.session_id, time.ctime())
logging.info("GUI has connected to session %d at %s", self.session.id, time.ctime())
tlv_data = ""
tlv_data += coreapi.CoreRegisterTlv.pack(RegisterTlvs.EXECUTE_SERVER.value, "core-daemon")
@ -535,7 +537,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
# TODO: add shutdown handler for session
self.session = self.coreemu.create_session(port, master=False)
# self.session.shutdown_handlers.append(self.session_shutdown)
logging.debug("created new session for client: %s", self.session.session_id)
logging.debug("created new session for client: %s", self.session.id)
# TODO: hack to associate this handler with this sessions broker for broadcasting
# TODO: broker needs to be pulled out of session to the server/handler level
@ -589,7 +591,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
:return:
"""
exception_data = ExceptionData(
session=str(self.session.session_id),
session=str(self.session.id),
node=node,
date=time.ctime(),
level=level.value,
@ -847,7 +849,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
try:
session.open_xml(file_name, start=True)
except:
self.coreemu.delete_session(session.session_id)
self.coreemu.delete_session(session.id)
raise
else:
thread = threading.Thread(
@ -905,7 +907,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
# find the session containing this client and set the session to master
for session in self.coreemu.sessions.itervalues():
if self in session.broker.session_clients:
logging.debug("setting session to master: %s", session.session_id)
logging.debug("setting session to master: %s", session.id)
session.master = True
break
@ -1588,7 +1590,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
logging.warn("session %s not found", session_id)
continue
logging.info("request to modify to session: %s", session.session_id)
logging.info("request to modify to session: %s", session.id)
if names is not None:
session.name = names[index]
@ -1621,7 +1623,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
self.remove_session_handlers()
self.session.broker.session_clients.remove(self)
if not self.session.broker.session_clients and not self.session.is_active():
self.coreemu.delete_session(self.session.session_id)
self.coreemu.delete_session(self.session.id)
# set session to join
self.session = session
@ -1724,7 +1726,7 @@ class CoreHandler(SocketServer.BaseRequestHandler):
type=ConfigFlags.UPDATE.value,
data_types=data_types,
data_values=values,
session=str(self.session.session_id),
session=str(self.session.id),
opaque=opaque
)
self.session.broadcast_config(config_data)
@ -1758,15 +1760,17 @@ class CoreHandler(SocketServer.BaseRequestHandler):
self.session.broadcast_config(config_data)
# send session metadata
data_values = "|".join(["%s=%s" % item for item in self.session.metadata.get_configs().iteritems()])
data_types = tuple(ConfigDataTypes.STRING.value for _ in self.session.metadata.get_configs())
config_data = ConfigData(
message_type=0,
object=self.session.metadata.name,
type=ConfigFlags.NONE.value,
data_types=data_types,
data_values=data_values
)
self.session.broadcast_config(config_data)
metadata_configs = self.session.metadata.get_configs()
if metadata_configs:
data_values = "|".join(["%s=%s" % item for item in metadata_configs.iteritems()])
data_types = tuple(ConfigDataTypes.STRING.value for _ in self.session.metadata.get_configs())
config_data = ConfigData(
message_type=0,
object=self.session.metadata.name,
type=ConfigFlags.NONE.value,
data_types=data_types,
data_values=data_values
)
self.session.broadcast_config(config_data)
logging.info("informed GUI about %d nodes and %d links", len(nodes_data), len(links_data))

View file

@ -570,7 +570,8 @@ class PyCoreNet(PyCoreObj):
delay=netif.getparam("delay"),
bandwidth=netif.getparam("bw"),
dup=netif.getparam("duplicate"),
jitter=netif.getparam("jitter")
jitter=netif.getparam("jitter"),
per=netif.getparam("loss")
)
all_links.append(link_data)
@ -587,7 +588,8 @@ class PyCoreNet(PyCoreObj):
delay=netif.getparam("delay"),
bandwidth=netif.getparam("bw"),
dup=netif.getparam("duplicate"),
jitter=netif.getparam("jitter")
jitter=netif.getparam("jitter"),
per=netif.getparam("loss")
)
netif.swapparams('_params_up')

View file

@ -29,6 +29,11 @@ class EmaneBypassModel(emanemodel.EmaneModel):
phy_library = "bypassphylayer"
phy_config = []
@classmethod
def load(cls, emane_prefix):
# ignore default logic
pass
# override config groups
@classmethod
def config_groups(cls):

View file

@ -37,13 +37,18 @@ class EmaneCommEffectModel(emanemodel.EmaneModel):
name = "emane_commeffect"
shim_library = "commeffectshim"
shim_xml = "/usr/share/emane/manifest/commeffectshim.xml"
shim_xml = "commeffectshim.xml"
shim_defaults = {}
config_shim = emanemanifest.parse(shim_xml, shim_defaults)
config_shim = []
# comm effect does not need the default phy and external configurations
phy_config = ()
external_config = ()
phy_config = []
external_config = []
@classmethod
def load(cls, emane_prefix):
shim_xml_path = os.path.join(emane_prefix, "share/emane/manifest", cls.shim_xml)
cls.config_shim = emanemanifest.parse(shim_xml_path, cls.shim_defaults)
@classmethod
def configurations(cls):

View file

@ -51,6 +51,7 @@ EMANE_MODELS = [
EmaneBypassModel,
EmaneTdmaModel
]
DEFAULT_EMANE_PREFIX = "/usr"
class EmaneManager(ModelManager):
@ -212,6 +213,8 @@ class EmaneManager(ModelManager):
"""
for emane_model in emane_models:
logging.info("loading emane model: %s", emane_model.__name__)
emane_prefix = self.session.options.get_config("emane_prefix", default=DEFAULT_EMANE_PREFIX)
emane_model.load(emane_prefix)
self.models[emane_model.name] = emane_model
def add_node(self, emane_node):

View file

@ -26,13 +26,13 @@ class EmaneModel(WirelessModel):
# default phy configuration settings, using the universal model
phy_library = None
phy_xml = "/usr/share/emane/manifest/emanephy.xml"
phy_xml = "emanephy.xml"
phy_defaults = {
"subid": "1",
"propagationmodel": "2ray",
"noisemode": "none"
}
phy_config = emanemanifest.parse(phy_xml, phy_defaults)
phy_config = []
# support for external configurations
external_config = [
@ -43,12 +43,42 @@ class EmaneModel(WirelessModel):
config_ignore = set()
@classmethod
def load(cls, emane_prefix):
"""
Called after being loaded within the EmaneManager. Provides configured emane_prefix for
parsing xml files.
:param str emane_prefix: configured emane prefix path
:return: nothing
"""
manifest_path = "share/emane/manifest"
# load mac configuration
mac_xml_path = os.path.join(emane_prefix, manifest_path, cls.mac_xml)
cls.mac_config = emanemanifest.parse(mac_xml_path, cls.mac_defaults)
# load phy configuration
phy_xml_path = os.path.join(emane_prefix, manifest_path, cls.phy_xml)
cls.phy_config = emanemanifest.parse(phy_xml_path, cls.phy_defaults)
@classmethod
def configurations(cls):
"""
Returns the combination all all configurations (mac, phy, and external).
:return: all configurations
:rtype: list[Configuration]
"""
return cls.mac_config + cls.phy_config + cls.external_config
@classmethod
def config_groups(cls):
"""
Returns the defined configuration groups.
:return: list of configuration groups.
:rtype: list[ConfigGroup]
"""
mac_len = len(cls.mac_config)
phy_len = len(cls.phy_config) + mac_len
config_len = len(cls.configurations())

View file

@ -1,8 +1,8 @@
"""
ieee80211abg.py: EMANE IEEE 802.11abg model for CORE
"""
import os
from core.emane import emanemanifest
from core.emane import emanemodel
@ -12,8 +12,12 @@ class EmaneIeee80211abgModel(emanemodel.EmaneModel):
# mac configuration
mac_library = "ieee80211abgmaclayer"
mac_xml = "/usr/share/emane/manifest/ieee80211abgmaclayer.xml"
mac_defaults = {
"pcrcurveuri": "/usr/share/emane/xml/models/mac/ieee80211abg/ieee80211pcr.xml",
}
mac_config = emanemanifest.parse(mac_xml, mac_defaults)
mac_xml = "ieee80211abgmaclayer.xml"
@classmethod
def load(cls, emane_prefix):
cls.mac_defaults["pcrcurveuri"] = os.path.join(
emane_prefix,
"share/emane/xml/models/mac/ieee80211abg/ieee80211pcr.xml"
)
super(EmaneIeee80211abgModel, cls).load(emane_prefix)

View file

@ -1,8 +1,8 @@
"""
rfpipe.py: EMANE RF-PIPE model for CORE
"""
import os
from core.emane import emanemanifest
from core.emane import emanemodel
@ -12,8 +12,12 @@ class EmaneRfPipeModel(emanemodel.EmaneModel):
# mac configuration
mac_library = "rfpipemaclayer"
mac_xml = "/usr/share/emane/manifest/rfpipemaclayer.xml"
mac_defaults = {
"pcrcurveuri": "/usr/share/emane/xml/models/mac/rfpipe/rfpipepcr.xml",
}
mac_config = emanemanifest.parse(mac_xml, mac_defaults)
mac_xml = "rfpipemaclayer.xml"
@classmethod
def load(cls, emane_prefix):
cls.mac_defaults["pcrcurveuri"] = os.path.join(
emane_prefix,
"share/emane/xml/models/mac/rfpipe/rfpipepcr.xml"
)
super(EmaneRfPipeModel, cls).load(emane_prefix)

View file

@ -7,7 +7,6 @@ import os
from core import constants
from core.conf import Configuration
from core.emane import emanemanifest
from core.emane import emanemodel
from core.enumerations import ConfigDataTypes
from core.misc import utils
@ -19,26 +18,30 @@ class EmaneTdmaModel(emanemodel.EmaneModel):
# mac configuration
mac_library = "tdmaeventschedulerradiomodel"
mac_xml = "/usr/share/emane/manifest/tdmaeventschedulerradiomodel.xml"
mac_defaults = {
"pcrcurveuri": "/usr/share/emane/xml/models/mac/tdmaeventscheduler/tdmabasemodelpcr.xml",
}
mac_config = emanemanifest.parse(mac_xml, mac_defaults)
mac_xml = "tdmaeventschedulerradiomodel.xml"
# add custom schedule options and ignore it when writing emane xml
schedule_name = "schedule"
default_schedule = os.path.join(constants.CORE_DATA_DIR, "examples", "tdma", "schedule.xml")
mac_config.insert(
0,
Configuration(
_id=schedule_name,
_type=ConfigDataTypes.STRING,
default=default_schedule,
label="TDMA schedule file (core)"
)
)
config_ignore = {schedule_name}
@classmethod
def load(cls, emane_prefix):
cls.mac_defaults["pcrcurveuri"] = os.path.join(
emane_prefix,
"share/emane/xml/models/mac/tdmaeventscheduler/tdmabasemodelpcr.xml"
)
super(EmaneTdmaModel, cls).load(emane_prefix)
cls.mac_config.insert(
0,
Configuration(
_id=cls.schedule_name,
_type=ConfigDataTypes.STRING,
default=cls.default_schedule,
label="TDMA schedule file (core)"
)
)
def post_startup(self):
"""
Logic to execute after the emane manager is finished with startup.

View file

@ -118,8 +118,8 @@ class IdGen(object):
class EmuSession(Session):
def __init__(self, session_id, config=None, mkdir=True):
super(EmuSession, self).__init__(session_id, config, mkdir)
def __init__(self, _id, config=None, mkdir=True):
super(EmuSession, self).__init__(_id, config, mkdir)
# object management
self.node_id_gen = IdGen()
@ -620,7 +620,7 @@ class EmuSession(Session):
:return: nothing
"""
logging.info("session(%s) shutting down", self.session_id)
logging.info("session(%s) shutting down", self.id)
self.set_state(EventTypes.DATACOLLECT_STATE, send_event=True)
self.set_state(EventTypes.SHUTDOWN_STATE, send_event=True)
super(EmuSession, self).shutdown()
@ -647,7 +647,7 @@ class EmuSession(Session):
:return: True if active, False otherwise
"""
result = self.state in {EventTypes.RUNTIME_STATE.value, EventTypes.DATACOLLECT_STATE.value}
logging.info("session(%s) checking if active: %s", self.session_id, result)
logging.info("session(%s) checking if active: %s", self.id, result)
return result
def open_xml(self, file_name, start=False):

View file

@ -183,13 +183,13 @@ class InterfaceData(object):
"""
Creates an InterfaceData object.
:param int _id:
:param str name:
:param str mac:
:param str ip4:
:param int ip4_mask:
:param str ip6:
:param int ip6_mask:
:param int _id: interface id
:param str name: name for interface
:param core.misc.ipaddress.MacAddress mac: mac address
:param str ip4: ipv4 address
:param int ip4_mask: ipv4 bit mask
:param str ip6: ipv6 address
:param int ip6_mask: ipv6 bit mask
"""
self.id = _id
self.name = name

View file

831
daemon/core/grpc/client.py Normal file
View file

@ -0,0 +1,831 @@
"""
gRpc client for interfacing with CORE, when gRPC mode is enabled.
"""
from __future__ import print_function
import logging
import threading
from contextlib import contextmanager
import grpc
from core.grpc import core_pb2
from core.grpc import core_pb2_grpc
from core.misc.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
class InterfaceHelper(object):
"""
Convenience class to help generate IP4 and IP6 addresses for gRPC clients.
"""
def __init__(self, ip4_prefix=None, ip6_prefix=None):
"""
Creates an InterfaceHelper object.
:param str ip4_prefix: ip4 prefix to use for generation
:param str ip6_prefix: ip6 prefix to use for generation
:raises ValueError: when both ip4 and ip6 prefixes have not been provided
"""
if not ip4_prefix and not ip6_prefix:
raise ValueError("ip4 or ip6 must be provided")
self.ip4 = None
if ip4_prefix:
self.ip4 = Ipv4Prefix(ip4_prefix)
self.ip6 = None
if ip6_prefix:
self.ip6 = Ipv6Prefix(ip6_prefix)
def ip4_address(self, node_id):
"""
Convenience method to return the IP4 address for a node.
:param int node_id: node id to get IP4 address for
:return: IP4 address or None
:rtype: str
"""
if not self.ip4:
raise ValueError("ip4 prefixes have not been set")
return str(self.ip4.addr(node_id))
def ip6_address(self, node_id):
"""
Convenience method to return the IP6 address for a node.
:param int node_id: node id to get IP6 address for
:return: IP4 address or None
:rtype: str
"""
if not self.ip6:
raise ValueError("ip6 prefixes have not been set")
return str(self.ip6.addr(node_id))
def create_interface(self, node_id, interface_id, name=None, mac=None):
"""
Creates interface data for linking nodes, using the nodes unique id for generation, along with a random
mac address, unless provided.
:param int node_id: node id to create interface for
:param int interface_id: interface id for interface
:param str name: name to set for interface, default is eth{id}
:param str mac: mac address to use for this interface, default is random generation
:return: new interface data for the provided node
:rtype: core_pb2.Interface
"""
# generate ip4 data
ip4 = None
ip4_mask = None
if self.ip4:
ip4 = str(self.ip4.addr(node_id))
ip4_mask = self.ip4.prefixlen
# generate ip6 data
ip6 = None
ip6_mask = None
if self.ip6:
ip6 = str(self.ip6.addr(node_id))
ip6_mask = self.ip6.prefixlen
# random mac
if not mac:
mac = MacAddress.random()
return core_pb2.Interface(
id=interface_id,
name=name,
ip4=ip4,
ip4mask=ip4_mask,
ip6=ip6,
ip6mask=ip6_mask,
mac=str(mac)
)
def stream_listener(stream, handler):
"""
Listen for stream events and provide them to the handler.
:param stream: grpc stream that will provide events
:param handler: function that handles an event
:return: nothing
"""
try:
for event in stream:
handler(event)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.CANCELLED:
logging.debug("stream closed")
else:
logging.exception("stream error")
def start_streamer(stream, handler):
"""
Convenience method for starting a grpc stream thread for handling streamed events.
:param stream: grpc stream that will provide events
:param handler: function that handles an event
:return: nothing
"""
thread = threading.Thread(target=stream_listener, args=(stream, handler))
thread.daemon = True
thread.start()
class CoreGrpcClient(object):
"""
Provides convenience methods for interfacing with the CORE grpc server.
"""
def __init__(self, address="localhost:50051"):
"""
Creates a CoreGrpcClient instance.
:param str address: grpc server address to connect to
"""
self.address = address
self.stub = None
self.channel = None
def create_session(self, _id=None):
"""
Create a session.
:param int _id: id for session, default is None and one will be created for you
:return: response with created session id
:rtype: core_pb2.CreateSessionResponse
"""
request = core_pb2.CreateSessionRequest(id=_id)
return self.stub.CreateSession(request)
def delete_session(self, _id):
"""
Delete a session.
:param int _id: id of session
:return: response with result of deletion success or failure
:rtype: core_pb2.DeleteSessionResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteSessionRequest(id=_id)
return self.stub.DeleteSession(request)
def get_sessions(self):
"""
Retrieves all currently known sessions.
:return: response with a list of currently known session, their state and number of nodes
:rtype: core_pb2.GetSessionsResponse
"""
return self.stub.GetSessions(core_pb2.GetSessionsRequest())
def get_session(self, _id):
"""
Retrieve a session.
:param int _id: id of session
:return: response with sessions state, nodes, and links
:rtype: core_pb2.GetSessionResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionRequest(id=_id)
return self.stub.GetSession(request)
def get_session_options(self, _id):
"""
Retrieve session options.
:param int _id: id of session
:return: response with a list of configuration groups
:rtype: core_pb2.GetSessionOptionsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionOptionsRequest(id=_id)
return self.stub.GetSessionOptions(request)
def set_session_options(self, _id, config):
"""
Set options for a session.
:param int _id: id of session
:param dict[str, str] config: configuration values to set
:return: response with result of success or failure
:rtype: core_pb2.SetSessionOptionsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetSessionOptionsRequest(id=_id, config=config)
return self.stub.SetSessionOptions(request)
def get_session_location(self, _id):
"""
Get session location.
:param int _id: id of session
:return: response with session position reference and scale
:rtype: core_pb2.GetSessionLocationResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetSessionLocationRequest(id=_id)
return self.stub.GetSessionLocation(request)
def set_session_location(self, _id, x=None, y=None, z=None, lat=None, lon=None, alt=None, scale=None):
"""
Set session location.
:param int _id: id of session
:param float x: x position
:param float y: y position
:param float z: z position
:param float lat: latitude position
:param float lon: longitude position
:param float alt: altitude position
:param float scale: geo scale
:return: response with result of success or failure
:rtype: core_pb2.SetSessionLocationResponse
:raises grpc.RpcError: when session doesn't exist
"""
position = core_pb2.Position(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
request = core_pb2.SetSessionLocationRequest(id=_id, position=position, scale=scale)
return self.stub.SetSessionLocation(request)
def set_session_state(self, _id, state):
"""
Set session state.
:param int _id: id of session
:param core_pb2.SessionState state: session state to transition to
:return: response with result of success or failure
:rtype: core_pb2.SetSessionStateResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetSessionStateRequest(id=_id, state=state)
return self.stub.SetSessionState(request)
def node_events(self, _id, handler):
"""
Listen for session node events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.NodeEventsRequest(id=_id)
stream = self.stub.NodeEvents(request)
start_streamer(stream, handler)
def link_events(self, _id, handler):
"""
Listen for session link events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.LinkEventsRequest(id=_id)
stream = self.stub.LinkEvents(request)
start_streamer(stream, handler)
def session_events(self, _id, handler):
"""
Listen for session events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SessionEventsRequest(id=_id)
stream = self.stub.SessionEvents(request)
start_streamer(stream, handler)
def config_events(self, _id, handler):
"""
Listen for session config events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.ConfigEventsRequest(id=_id)
stream = self.stub.ConfigEvents(request)
start_streamer(stream, handler)
def exception_events(self, _id, handler):
"""
Listen for session exception events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.ExceptionEventsRequest(id=_id)
stream = self.stub.ExceptionEvents(request)
start_streamer(stream, handler)
def file_events(self, _id, handler):
"""
Listen for session file events.
:param int _id: id of session
:param handler: handler for every event
:return: nothing
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.FileEventsRequest(id=_id)
stream = self.stub.FileEvents(request)
start_streamer(stream, handler)
def add_node(self, session, node):
"""
Add node to session.
:param int session: session id
:param core_pb2.Node node: node to add
:return: response with node id
:rtype: core_pb2.AddNodeResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.AddNodeRequest(session=session, node=node)
return self.stub.AddNode(request)
def get_node(self, session, _id):
"""
Get node details.
:param int session: session id
:param int _id: node id
:return: response with node details
:rtype: core_pb2.GetNodeResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeRequest(session=session, id=_id)
return self.stub.GetNode(request)
def edit_node(self, session, _id, position):
"""
Edit a node, currently only changes position.
:param int session: session id
:param int _id: node id
:param core_pb2.Position position: position to set node to
:return: response with result of success or failure
:rtype: core_pb2.EditNodeResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.EditNodeRequest(session=session, id=_id, position=position)
return self.stub.EditNode(request)
def delete_node(self, session, _id):
"""
Delete node from session.
:param int session: session id
:param int _id: node id
:return: response with result of success or failure
:rtype: core_pb2.DeleteNodeResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteNodeRequest(session=session, id=_id)
return self.stub.DeleteNode(request)
def get_node_links(self, session, _id):
"""
Get current links for a node.
:param int session: session id
:param int _id: node id
:return: response with a list of links
:rtype: core_pb2.GetNodeLinksResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeLinksRequest(session=session, id=_id)
return self.stub.GetNodeLinks(request)
def add_link(self, session, node_one, node_two, interface_one=None, interface_two=None, options=None):
"""
Add a link between nodes.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param core_pb2.Interface interface_one: node one interface data
:param core_pb2.Interface interface_two: node two interface data
:param core_pb2.LinkOptions options: options for link (jitter, bandwidth, etc)
:return: response with result of success or failure
:rtype: core_pb2.AddLinkResponse
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
link = core_pb2.Link(
node_one=node_one, node_two=node_two, type=core_pb2.LINK_WIRED,
interface_one=interface_one, interface_two=interface_two, options=options)
request = core_pb2.AddLinkRequest(session=session, link=link)
return self.stub.AddLink(request)
def edit_link(self, session, node_one, node_two, options, interface_one=None, interface_two=None):
"""
Edit a link between nodes.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param core_pb2.LinkOptions options: options for link (jitter, bandwidth, etc)
:param int interface_one: node one interface id
:param int interface_two: node two interface id
:return: response with result of success or failure
:rtype: core_pb2.EditLinkResponse
:raises grpc.RpcError: when session or one of the nodes don't exist
"""
request = core_pb2.EditLinkRequest(
session=session, node_one=node_one, node_two=node_two, options=options,
interface_one=interface_one, interface_two=interface_two)
return self.stub.EditLink(request)
def delete_link(self, session, node_one, node_two, interface_one=None, interface_two=None):
"""
Delete a link between nodes.
:param int session: session id
:param int node_one: node one id
:param int node_two: node two id
:param int interface_one: node one interface id
:param int interface_two: node two interface id
:return: response with result of success or failure
:rtype: core_pb2.DeleteLinkResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.DeleteLinkRequest(
session=session, node_one=node_one, node_two=node_two,
interface_one=interface_one, interface_two=interface_two)
return self.stub.DeleteLink(request)
def get_hooks(self, session):
"""
Get all hook scripts.
:param int session: session id
:return: response with a list of hooks
:rtype: core_pb2.GetHooksResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetHooksRequest(session=session)
return self.stub.GetHooks(request)
def add_hook(self, session, state, file_name, file_data):
"""
Add hook scripts.
:param int session: session id
:param core_pb2.SessionState state: state to trigger hook
:param str file_name: name of file for hook script
:param bytes file_data: hook script contents
:return: response with result of success or failure
:rtype: core_pb2.AddHookResponse
:raises grpc.RpcError: when session doesn't exist
"""
hook = core_pb2.Hook(state=state, file=file_name, data=file_data)
request = core_pb2.AddHookRequest(session=session, hook=hook)
return self.stub.AddHook(request)
def get_mobility_configs(self, session):
"""
Get all mobility configurations.
:param int session: session id
:return: response with a dict of node ids to mobility configurations
:rtype: core_pb2.GetMobilityConfigsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetMobilityConfigsRequest(session=session)
return self.stub.GetMobilityConfigs(request)
def get_mobility_config(self, session, _id):
"""
Get mobility configuration for a node.
:param int session: session id
:param int _id: node id
:return: response with a list of configuration groups
:rtype: core_pb2.GetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetMobilityConfigRequest(session=session, id=_id)
return self.stub.GetMobilityConfig(request)
def set_mobility_config(self, session, _id, config):
"""
Set mobility configuration for a node.
:param int session: session id
:param int _id: node id
:param dict[str, str] config: mobility configuration
:return: response with result of success or failure
:rtype: core_pb2.SetMobilityConfigResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetMobilityConfigRequest(session=session, id=_id, config=config)
return self.stub.SetMobilityConfig(request)
def mobility_action(self, session, _id, action):
"""
Send a mobility action for a node.
:param int session: session id
:param int _id: node id
:param core_pb2.ServiceAction action: action to take
:return: response with result of success or failure
:rtype: core_pb2.MobilityActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.MobilityActionRequest(session=session, id=_id, action=action)
return self.stub.MobilityAction(request)
def get_services(self):
"""
Get all currently loaded services.
:return: response with a list of services
:rtype: core_pb2.GetServicesResponse
"""
request = core_pb2.GetServicesRequest()
return self.stub.GetServices(request)
def get_service_defaults(self, session):
"""
Get default services for different default node models.
:param int session: session id
:return: response with a dict of node model to a list of services
:rtype: core_pb2.GetServiceDefaultsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetServiceDefaultsRequest(session=session)
return self.stub.GetServiceDefaults(request)
def set_service_defaults(self, session, service_defaults):
"""
Set default services for node models.
:param int session: session id
:param dict service_defaults: node models to lists of services
:return: response with result of success or failure
:rtype: core_pb2.SetServiceDefaultsResponse
:raises grpc.RpcError: when session doesn't exist
"""
defaults = []
for node_type in service_defaults:
services = service_defaults[node_type]
default = core_pb2.ServiceDefaults(node_type=node_type, services=services)
defaults.append(default)
request = core_pb2.SetServiceDefaultsRequest(session=session, defaults=defaults)
return self.stub.SetServiceDefaults(request)
def get_node_service(self, session, _id, service):
"""
Get service data for a node.
:param int session: session id
:param int _id: node id
:param str service: service name
:return: response with node service data
:rtype: core_pb2.GetNodeServiceResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceRequest(session=session, id=_id, service=service)
return self.stub.GetNodeService(request)
def get_node_service_file(self, session, _id, service, file_name):
"""
Get a service file for a node.
:param int session: session id
:param int _id: node id
:param str service: service name
:param str file_name: file name to get data for
:return: response with file data
:rtype: core_pb2.GetNodeServiceFileResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.GetNodeServiceFileRequest(session=session, id=_id, service=service, file=file_name)
return self.stub.GetNodeServiceFile(request)
def set_node_service(self, session, _id, service, startup, validate, shutdown):
"""
Set service data for a node.
:param int session: session id
:param int _id: node id
:param str service: service name
:param list startup: startup commands
:param list validate: validation commands
:param list shutdown: shutdown commands
:return: response with result of success or failure
:rtype: core_pb2.SetNodeServiceResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceRequest(
session=session, id=_id, service=service, startup=startup, validate=validate, shutdown=shutdown)
return self.stub.SetNodeService(request)
def set_node_service_file(self, session, _id, service, file_name, data):
"""
Set a service file for a node.
:param int session: session id
:param int _id: node id
:param str service: service name
:param str file_name: file name to save
:param bytes data: data to save for file
:return: response with result of success or failure
:rtype: core_pb2.SetNodeServiceFileResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.SetNodeServiceFileRequest(
session=session, id=_id, service=service, file=file_name, data=data)
return self.stub.SetNodeServiceFile(request)
def service_action(self, session, _id, service, action):
"""
Send an action to a service for a node.
:param int session: session id
:param int _id: node id
:param str service: service name
:param core_pb2.ServiceAction action: action for service (start, stop, restart, validate)
:return: response with result of success or failure
:rtype: core_pb2.ServiceActionResponse
:raises grpc.RpcError: when session or node doesn't exist
"""
request = core_pb2.ServiceActionRequest(session=session, id=_id, service=service, action=action)
return self.stub.ServiceAction(request)
def get_wlan_config(self, session, _id):
"""
Get wlan configuration for a node.
:param int session: session id
:param int _id: node id
:return: response with a list of configuration groups
:rtype: core_pb2.GetWlanConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetWlanConfigRequest(session=session, id=_id)
return self.stub.GetWlanConfig(request)
def set_wlan_config(self, session, _id, config):
"""
Set wlan configuration for a node.
:param int session: session id
:param int _id: node id
:param dict[str, str] config: wlan configuration
:return: response with result of success or failure
:rtype: core_pb2.SetWlanConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetWlanConfigRequest(session=session, id=_id, config=config)
return self.stub.SetWlanConfig(request)
def get_emane_config(self, session):
"""
Get session emane configuration.
:param int session: session id
:return: response with a list of configuration groups
:rtype: core_pb2.GetEmaneConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneConfigRequest(session=session)
return self.stub.GetEmaneConfig(request)
def set_emane_config(self, session, config):
"""
Set session emane configuration.
:param int session: session id
:param dict[str, str] config: emane configuration
:return: response with result of success or failure
:rtype: core_pb2.SetEmaneConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetEmaneConfigRequest(session=session, config=config)
return self.stub.SetEmaneConfig(request)
def get_emane_models(self, session):
"""
Get session emane models.
:param int session: session id
:return: response with a list of emane models
:rtype: core_pb2.GetEmaneModelsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelsRequest(session=session)
return self.stub.GetEmaneModels(request)
def get_emane_model_config(self, session, _id, model, interface_id=-1):
"""
Get emane model configuration for a node or a node's interface.
:param int session: session id
:param int _id: node id
:param str model: emane model name
:param int interface_id: node interface id
:return: response with a list of configuration groups
:rtype: core_pb2.GetEmaneModelConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelConfigRequest(session=session, id=_id, model=model, interface=interface_id)
return self.stub.GetEmaneModelConfig(request)
def set_emane_model_config(self, session, _id, model, config, interface_id=-1):
"""
Set emane model configuration for a node or a node's interface.
:param int session: session id
:param int _id: node id
:param str model: emane model name
:param dict[str, str] config: emane model configuration
:param int interface_id: node interface id
:return: response with result of success or failure
:rtype: core_pb2.SetEmaneModelConfigResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.SetEmaneModelConfigRequest(
session=session, id=_id, model=model, config=config, interface=interface_id)
return self.stub.SetEmaneModelConfig(request)
def get_emane_model_configs(self, session):
"""
Get all emane model configurations for a session.
:param int session: session id
:return: response with a dictionary of node/interface ids to configurations
:rtype: core_pb2.GetEmaneModelConfigsResponse
:raises grpc.RpcError: when session doesn't exist
"""
request = core_pb2.GetEmaneModelConfigsRequest(session=session)
return self.stub.GetEmaneModelConfigs(request)
def save_xml(self, session, file_path):
"""
Save the current scenario to an XML file.
:param int session: session id
:param str file_path: local path to save scenario XML file to
:return: nothing
"""
request = core_pb2.SaveXmlRequest(session=session)
response = self.stub.SaveXml(request)
with open(file_path, "wb") as xml_file:
xml_file.write(response.data)
def open_xml(self, file_path):
"""
Load a local scenario XML file to open as a new session.
:param str file_path: path of scenario XML file
:return: response with opened session id
:rtype: core_pb2.OpenXmlResponse
"""
with open(file_path, "rb") as xml_file:
data = xml_file.read()
request = core_pb2.OpenXmlRequest(data=data)
return self.stub.OpenXml(request)
def connect(self):
"""
Open connection to server, must be closed manually.
:return: nothing
"""
self.channel = grpc.insecure_channel(self.address)
self.stub = core_pb2_grpc.CoreApiStub(self.channel)
def close(self):
"""
Close currently opened server channel connection.
:return: nothing
"""
if self.channel:
self.channel.close()
self.channel = None
@contextmanager
def context_connect(self):
"""
Makes a context manager based connection to the server, will close after context ends.
:return: nothing
"""
try:
self.connect()
yield
finally:
self.close()

888
daemon/core/grpc/server.py Normal file
View file

@ -0,0 +1,888 @@
import atexit
import logging
import os
import tempfile
import time
from Queue import Queue, Empty
import grpc
from concurrent import futures
from core.emulator.emudata import NodeOptions, InterfaceData, LinkOptions
from core.enumerations import NodeTypes, EventTypes, LinkTypes
from core.grpc import core_pb2
from core.grpc import core_pb2_grpc
from core.misc import nodeutils
from core.misc.ipaddress import MacAddress
from core.mobility import BasicRangeModel, Ns2ScriptedMobility
from core.service import ServiceManager
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
def convert_value(value):
if value is not None:
value = str(value)
return value
def get_config_groups(config, configurable_options):
groups = []
config_options = []
for configuration in configurable_options.configurations():
value = config[configuration.id]
config_option = core_pb2.ConfigOption()
config_option.label = configuration.label
config_option.name = configuration.id
config_option.value = value
config_option.type = configuration.type.value
config_option.select.extend(configuration.options)
config_options.append(config_option)
for config_group in configurable_options.config_groups():
start = config_group.start - 1
stop = config_group.stop
options = config_options[start: stop]
config_group_proto = core_pb2.ConfigGroup(name=config_group.name, options=options)
groups.append(config_group_proto)
return groups
def get_links(session, node):
links = []
for link_data in node.all_link_data(0):
link = convert_link(session, link_data)
links.append(link)
return links
def get_emane_model_id(_id, interface):
if interface >= 0:
return _id * 1000 + interface
else:
return _id
def convert_link(session, link_data):
interface_one = None
if link_data.interface1_id is not None:
node = session.get_object(link_data.node1_id)
interface = node.netif(link_data.interface1_id)
interface_one = core_pb2.Interface(
id=link_data.interface1_id, name=interface.name, mac=convert_value(link_data.interface1_mac),
ip4=convert_value(link_data.interface1_ip4), ip4mask=link_data.interface1_ip4_mask,
ip6=convert_value(link_data.interface1_ip6), ip6mask=link_data.interface1_ip6_mask)
interface_two = None
if link_data.interface2_id is not None:
node = session.get_object(link_data.node2_id)
interface = node.netif(link_data.interface2_id)
interface_two = core_pb2.Interface(
id=link_data.interface2_id, name=interface.name, mac=convert_value(link_data.interface2_mac),
ip4=convert_value(link_data.interface2_ip4), ip4mask=link_data.interface2_ip4_mask,
ip6=convert_value(link_data.interface2_ip6), ip6mask=link_data.interface2_ip6_mask)
options = core_pb2.LinkOptions(
opaque=link_data.opaque,
jitter=link_data.jitter,
key=link_data.key,
mburst=link_data.mburst,
mer=link_data.mer,
per=link_data.per,
bandwidth=link_data.bandwidth,
burst=link_data.burst,
delay=link_data.delay,
dup=link_data.dup,
unidirectional=link_data.unidirectional
)
return core_pb2.Link(
type=link_data.link_type, node_one=link_data.node1_id, node_two=link_data.node2_id,
interface_one=interface_one, interface_two=interface_two, options=options
)
class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def __init__(self, coreemu):
super(CoreGrpcServer, self).__init__()
self.coreemu = coreemu
self.running = True
self.server = None
atexit.register(self._exit_handler)
def _exit_handler(self):
logging.debug("catching exit, stop running")
self.running = False
def _is_running(self, context):
return self.running and context.is_active()
def _cancel_stream(self, context):
context.abort(grpc.StatusCode.CANCELLED, "server stopping")
def listen(self, address="[::]:50051"):
logging.info("starting grpc api: %s", address)
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
core_pb2_grpc.add_CoreApiServicer_to_server(self, self.server)
self.server.add_insecure_port(address)
self.server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
self.server.stop(None)
def get_session(self, _id, context):
session = self.coreemu.sessions.get(_id)
if not session:
context.abort(grpc.StatusCode.NOT_FOUND, "session {} not found".format(_id))
return session
def get_node(self, session, _id, context):
try:
return session.get_object(_id)
except KeyError:
context.abort(grpc.StatusCode.NOT_FOUND, "node {} not found".format(_id))
def CreateSession(self, request, context):
logging.debug("create session: %s", request)
session = self.coreemu.create_session(request.id)
session.set_state(EventTypes.DEFINITION_STATE)
session.location.setrefgeo(47.57917, -122.13232, 2.0)
session.location.refscale = 150000.0
return core_pb2.CreateSessionResponse(id=session.id, state=session.state)
def DeleteSession(self, request, context):
logging.debug("delete session: %s", request)
result = self.coreemu.delete_session(request.id)
return core_pb2.DeleteSessionResponse(result=result)
def GetSessions(self, request, context):
logging.debug("get sessions: %s", request)
sessions = []
for session_id in self.coreemu.sessions:
session = self.coreemu.sessions[session_id]
session_summary = core_pb2.SessionSummary(
id=session_id, state=session.state, nodes=session.get_node_count())
sessions.append(session_summary)
return core_pb2.GetSessionsResponse(sessions=sessions)
def GetSessionLocation(self, request, context):
logging.debug("get session location: %s", request)
session = self.get_session(request.id, context)
x, y, z = session.location.refxyz
lat, lon, alt = session.location.refgeo
position = core_pb2.Position(x=x, y=y, z=z, lat=lat, lon=lon, alt=alt)
return core_pb2.GetSessionLocationResponse(position=position, scale=session.location.refscale)
def SetSessionLocation(self, request, context):
logging.debug("set session location: %s", request)
session = self.get_session(request.id, context)
session.location.refxyz = (request.position.x, request.position.y, request.position.z)
session.location.setrefgeo(request.position.lat, request.position.lon, request.position.alt)
session.location.refscale = request.scale
return core_pb2.SetSessionLocationResponse(result=True)
def SetSessionState(self, request, context):
logging.debug("set session state: %s", request)
session = self.get_session(request.id, context)
try:
state = EventTypes(request.state)
session.set_state(state)
if state == EventTypes.INSTANTIATION_STATE:
if not os.path.exists(session.session_dir):
os.mkdir(session.session_dir)
session.instantiate()
elif state == EventTypes.SHUTDOWN_STATE:
session.shutdown()
elif state == EventTypes.DATACOLLECT_STATE:
session.data_collect()
elif state == EventTypes.DEFINITION_STATE:
session.clear()
result = True
except KeyError:
result = False
return core_pb2.SetSessionStateResponse(result=result)
def GetSessionOptions(self, request, context):
logging.debug("get session options: %s", request)
session = self.get_session(request.id, context)
config = session.options.get_configs()
defaults = session.options.default_values()
defaults.update(config)
groups = get_config_groups(defaults, session.options)
return core_pb2.GetSessionOptionsResponse(groups=groups)
def SetSessionOptions(self, request, context):
logging.debug("set session options: %s", request)
session = self.get_session(request.id, context)
config = session.options.get_configs()
config.update(request.config)
return core_pb2.SetSessionOptionsResponse(result=True)
def GetSession(self, request, context):
logging.debug("get session: %s", request)
session = self.get_session(request.id, context)
links = []
nodes = []
for node_id in session.objects:
node = session.objects[node_id]
if not isinstance(node.objid, int):
continue
node_type = nodeutils.get_node_type(node.__class__).value
model = getattr(node, "type", None)
position = core_pb2.Position(x=node.position.x, y=node.position.y, z=node.position.z)
services = getattr(node, "services", [])
if services is None:
services = []
services = [x.name for x in services]
emane_model = None
if nodeutils.is_node(node, NodeTypes.EMANE):
emane_model = node.model.name
node_proto = core_pb2.Node(
id=node.objid, name=node.name, emane=emane_model, model=model,
type=node_type, position=position, services=services)
nodes.append(node_proto)
node_links = get_links(session, node)
links.extend(node_links)
session_proto = core_pb2.Session(state=session.state, nodes=nodes, links=links)
return core_pb2.GetSessionResponse(session=session_proto)
def NodeEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.node_handlers.append(queue.put)
while self._is_running(context):
try:
node = queue.get(timeout=1)
position = core_pb2.Position(x=node.x_position, y=node.y_position)
services = node.services or ""
services = services.split("|")
node_proto = core_pb2.Node(
id=node.id, name=node.name, model=node.model, position=position, services=services)
node_event = core_pb2.NodeEvent(node=node_proto)
yield node_event
except Empty:
continue
self._cancel_stream(context)
def LinkEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.link_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
interface_one = None
if event.interface1_id is not None:
interface_one = core_pb2.Interface(
id=event.interface1_id, name=event.interface1_name, mac=convert_value(event.interface1_mac),
ip4=convert_value(event.interface1_ip4), ip4mask=event.interface1_ip4_mask,
ip6=convert_value(event.interface1_ip6), ip6mask=event.interface1_ip6_mask)
interface_two = None
if event.interface2_id is not None:
interface_two = core_pb2.Interface(
id=event.interface2_id, name=event.interface2_name, mac=convert_value(event.interface2_mac),
ip4=convert_value(event.interface2_ip4), ip4mask=event.interface2_ip4_mask,
ip6=convert_value(event.interface2_ip6), ip6mask=event.interface2_ip6_mask)
options = core_pb2.LinkOptions(
opaque=event.opaque,
jitter=event.jitter,
key=event.key,
mburst=event.mburst,
mer=event.mer,
per=event.per,
bandwidth=event.bandwidth,
burst=event.burst,
delay=event.delay,
dup=event.dup,
unidirectional=event.unidirectional
)
link = core_pb2.Link(
type=event.link_type, node_one=event.node1_id, node_two=event.node2_id,
interface_one=interface_one, interface_two=interface_two, options=options)
link_event = core_pb2.LinkEvent(message_type=event.message_type, link=link)
yield link_event
except Empty:
continue
self._cancel_stream(context)
def SessionEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.event_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
event_time = event.time
if event_time is not None:
event_time = float(event_time)
session_event = core_pb2.SessionEvent(
node=event.node,
event=event.event_type,
name=event.name,
data=event.data,
time=event_time,
session=session.id
)
yield session_event
except Empty:
continue
self._cancel_stream(context)
def ConfigEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.config_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
config_event = core_pb2.ConfigEvent(
message_type=event.message_type,
node=event.node,
object=event.object,
type=event.type,
captions=event.captions,
bitmap=event.bitmap,
data_values=event.data_values,
possible_values=event.possible_values,
groups=event.groups,
session=event.session,
interface=event.interface_number,
network_id=event.network_id,
opaque=event.opaque,
data_types=event.data_types
)
yield config_event
except Empty:
continue
self._cancel_stream(context)
def ExceptionEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.exception_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
exception_event = core_pb2.ExceptionEvent(
node=event.node,
session=int(event.session),
level=event.level.value,
source=event.source,
date=event.date,
text=event.text,
opaque=event.opaque
)
yield exception_event
except Empty:
continue
self._cancel_stream(context)
def FileEvents(self, request, context):
session = self.get_session(request.id, context)
queue = Queue()
session.file_handlers.append(queue.put)
while self._is_running(context):
try:
event = queue.get(timeout=1)
file_event = core_pb2.FileEvent(
message_type=event.message_type,
node=event.node,
name=event.name,
mode=event.mode,
number=event.number,
type=event.type,
source=event.source,
session=event.session,
data=event.data,
compressed_data=event.compressed_data
)
yield file_event
except Empty:
continue
self._cancel_stream(context)
def AddNode(self, request, context):
logging.debug("add node: %s", request)
session = self.get_session(request.session, context)
node_proto = request.node
node_id = node_proto.id
node_type = node_proto.type
if node_type is None:
node_type = NodeTypes.DEFAULT.value
node_type = NodeTypes(node_type)
node_options = NodeOptions(name=node_proto.name, model=node_proto.model)
node_options.icon = node_proto.icon
node_options.opaque = node_proto.opaque
node_options.services = node_proto.services
position = node_proto.position
node_options.set_position(position.x, position.y)
node_options.set_location(position.lat, position.lon, position.alt)
node = session.add_node(_type=node_type, _id=node_id, node_options=node_options)
# configure emane if provided
emane_model = node_proto.emane
if emane_model:
session.emane.set_model_config(node_id, emane_model)
return core_pb2.AddNodeResponse(id=node.objid)
def GetNode(self, request, context):
logging.debug("get node: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
interfaces = []
for interface_id, interface in node._netif.iteritems():
net_id = None
if interface.net:
net_id = interface.net.objid
interface_proto = core_pb2.Interface(
id=interface_id, netid=net_id, name=interface.name, mac=str(interface.hwaddr),
mtu=interface.mtu, flowid=interface.flow_id)
interfaces.append(interface_proto)
emane_model = None
if nodeutils.is_node(node, NodeTypes.EMANE):
emane_model = node.model.name
services = [x.name for x in getattr(node, "services", [])]
position = core_pb2.Position(x=node.position.x, y=node.position.y, z=node.position.z)
node_type = nodeutils.get_node_type(node.__class__).value
node = core_pb2.Node(
id=node.objid, name=node.name, type=node_type, emane=emane_model, model=node.type, position=position,
services=services)
return core_pb2.GetNodeResponse(node=node, interfaces=interfaces)
def EditNode(self, request, context):
logging.debug("edit node: %s", request)
session = self.get_session(request.session, context)
node_id = request.id
node_options = NodeOptions()
x = request.position.x
y = request.position.y
node_options.set_position(x, y)
lat = request.position.lat
lon = request.position.lon
alt = request.position.alt
node_options.set_location(lat, lon, alt)
result = session.update_node(node_id, node_options)
return core_pb2.EditNodeResponse(result=result)
def DeleteNode(self, request, context):
logging.debug("delete node: %s", request)
session = self.get_session(request.session, context)
result = session.delete_node(request.id)
return core_pb2.DeleteNodeResponse(result=result)
def GetNodeLinks(self, request, context):
logging.debug("get node links: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
links = get_links(session, node)
return core_pb2.GetNodeLinksResponse(links=links)
def AddLink(self, request, context):
logging.debug("add link: %s", request)
session = self.get_session(request.session, context)
# validate node exist
self.get_node(session, request.link.node_one, context)
self.get_node(session, request.link.node_two, context)
node_one = request.link.node_one
node_two = request.link.node_two
interface_one = None
interface_one_data = request.link.interface_one
if interface_one_data:
name = interface_one_data.name
if name == "":
name = None
mac = interface_one_data.mac
if mac == "":
mac = None
else:
mac = MacAddress.from_string(mac)
interface_one = InterfaceData(
_id=interface_one_data.id,
name=name,
mac=mac,
ip4=interface_one_data.ip4,
ip4_mask=interface_one_data.ip4mask,
ip6=interface_one_data.ip6,
ip6_mask=interface_one_data.ip6mask,
)
interface_two = None
interface_two_data = request.link.interface_two
if interface_two_data:
name = interface_two_data.name
if name == "":
name = None
mac = interface_two_data.mac
if mac == "":
mac = None
else:
mac = MacAddress.from_string(mac)
interface_two = InterfaceData(
_id=interface_two_data.id,
name=name,
mac=mac,
ip4=interface_two_data.ip4,
ip4_mask=interface_two_data.ip4mask,
ip6=interface_two_data.ip6,
ip6_mask=interface_two_data.ip6mask,
)
link_type = None
link_type_value = request.link.type
if link_type_value is not None:
link_type = LinkTypes(link_type_value)
options_data = request.link.options
link_options = LinkOptions(_type=link_type)
if options_data:
link_options.delay = options_data.delay
link_options.bandwidth = options_data.bandwidth
link_options.per = options_data.per
link_options.dup = options_data.dup
link_options.jitter = options_data.jitter
link_options.mer = options_data.mer
link_options.burst = options_data.burst
link_options.mburst = options_data.mburst
link_options.unidirectional = options_data.unidirectional
link_options.key = options_data.key
link_options.opaque = options_data.opaque
session.add_link(node_one, node_two, interface_one, interface_two, link_options=link_options)
return core_pb2.AddLinkResponse(result=True)
def EditLink(self, request, context):
logging.debug("edit link: %s", request)
session = self.get_session(request.session, context)
node_one = request.node_one
node_two = request.node_two
interface_one_id = request.interface_one
interface_two_id = request.interface_two
options_data = request.options
link_options = LinkOptions()
link_options.delay = options_data.delay
link_options.bandwidth = options_data.bandwidth
link_options.per = options_data.per
link_options.dup = options_data.dup
link_options.jitter = options_data.jitter
link_options.mer = options_data.mer
link_options.burst = options_data.burst
link_options.mburst = options_data.mburst
link_options.unidirectional = options_data.unidirectional
link_options.key = options_data.key
link_options.opaque = options_data.opaque
session.update_link(node_one, node_two, interface_one_id, interface_two_id, link_options)
return core_pb2.EditLinkResponse(result=True)
def DeleteLink(self, request, context):
logging.debug("delete link: %s", request)
session = self.get_session(request.session, context)
node_one = request.node_one
node_two = request.node_two
interface_one = request.interface_one
interface_two = request.interface_two
session.delete_link(node_one, node_two, interface_one, interface_two)
return core_pb2.DeleteLinkResponse(result=True)
def GetHooks(self, request, context):
logging.debug("get hooks: %s", request)
session = self.get_session(request.session, context)
hooks = []
for state, state_hooks in session._hooks.iteritems():
for file_name, file_data in state_hooks:
hook = core_pb2.Hook(state=state, file=file_name, data=file_data)
hooks.append(hook)
return core_pb2.GetHooksResponse(hooks=hooks)
def AddHook(self, request, context):
logging.debug("add hook: %s", request)
session = self.get_session(request.session, context)
hook = request.hook
session.add_hook(hook.state, hook.file, None, hook.data)
return core_pb2.AddHookResponse(result=True)
def GetMobilityConfigs(self, request, context):
logging.debug("get mobility configs: %s", request)
session = self.get_session(request.session, context)
response = core_pb2.GetMobilityConfigsResponse()
for node_id, model_config in session.mobility.node_configurations.iteritems():
if node_id == -1:
continue
for model_name in model_config.iterkeys():
if model_name != Ns2ScriptedMobility.name:
continue
config = session.mobility.get_model_config(node_id, model_name)
groups = get_config_groups(config, Ns2ScriptedMobility)
response.configs[node_id].groups.extend(groups)
return response
def GetMobilityConfig(self, request, context):
logging.debug("get mobility config: %s", request)
session = self.get_session(request.session, context)
config = session.mobility.get_model_config(request.id, Ns2ScriptedMobility.name)
groups = get_config_groups(config, Ns2ScriptedMobility)
return core_pb2.GetMobilityConfigResponse(groups=groups)
def SetMobilityConfig(self, request, context):
logging.debug("set mobility config: %s", request)
session = self.get_session(request.session, context)
session.mobility.set_model_config(request.id, Ns2ScriptedMobility.name, request.config)
return core_pb2.SetMobilityConfigResponse(result=True)
def MobilityAction(self, request, context):
logging.debug("mobility action: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
result = True
if request.action == core_pb2.MOBILITY_START:
node.mobility.start()
elif request.action == core_pb2.MOBILITY_PAUSE:
node.mobility.pause()
elif request.action == core_pb2.MOBILITY_STOP:
node.mobility.stop(move_initial=True)
else:
result = False
return core_pb2.MobilityActionResponse(result=result)
def GetServices(self, request, context):
logging.debug("get services: %s", request)
services = []
for service in ServiceManager.services.itervalues():
service_proto = core_pb2.Service(group=service.group, name=service.name)
services.append(service_proto)
return core_pb2.GetServicesResponse(services=services)
def GetServiceDefaults(self, request, context):
logging.debug("get service defaults: %s", request)
session = self.get_session(request.session, context)
all_service_defaults = []
for node_type in session.services.default_services:
services = session.services.default_services[node_type]
service_defaults = core_pb2.ServiceDefaults(node_type=node_type, services=services)
all_service_defaults.append(service_defaults)
return core_pb2.GetServiceDefaultsResponse(defaults=all_service_defaults)
def SetServiceDefaults(self, request, context):
logging.debug("set service defaults: %s", request)
session = self.get_session(request.session, context)
session.services.default_services.clear()
for service_defaults in request.defaults:
session.services.default_services[service_defaults.node_type] = service_defaults.services
return core_pb2.SetServiceDefaultsResponse(result=True)
def GetNodeService(self, request, context):
logging.debug("get node service: %s", request)
session = self.get_session(request.session, context)
service = session.services.get_service(request.id, request.service, default_service=True)
service_proto = core_pb2.NodeServiceData(
executables=service.executables,
dependencies=service.dependencies,
dirs=service.dirs,
configs=service.configs,
startup=service.startup,
validate=service.validate,
validation_mode=service.validation_mode.value,
validation_timer=service.validation_timer,
shutdown=service.shutdown,
meta=service.meta
)
return core_pb2.GetNodeServiceResponse(service=service_proto)
def GetNodeServiceFile(self, request, context):
logging.debug("get node service file: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
service = None
for current_service in node.services:
if current_service.name == request.service:
service = current_service
break
if not service:
context.abort(grpc.StatusCode.NOT_FOUND, "service not found")
file_data = session.services.get_service_file(node, request.service, request.file)
return core_pb2.GetNodeServiceFileResponse(data=file_data.data)
def SetNodeService(self, request, context):
logging.debug("set node service: %s", request)
session = self.get_session(request.session, context)
session.services.set_service(request.id, request.service)
service = session.services.get_service(request.id, request.service)
service.startup = tuple(request.startup)
service.validate = tuple(request.validate)
service.shutdown = tuple(request.shutdown)
return core_pb2.SetNodeServiceResponse(result=True)
def SetNodeServiceFile(self, request, context):
logging.debug("set node service file: %s", request)
session = self.get_session(request.session, context)
session.services.set_service_file(request.id, request.service, request.file, request.data)
return core_pb2.SetNodeServiceFileResponse(result=True)
def ServiceAction(self, request, context):
logging.debug("service action: %s", request)
session = self.get_session(request.session, context)
node = self.get_node(session, request.id, context)
service = None
for current_service in node.services:
if current_service.name == request.service:
service = current_service
break
if not service:
context.abort(grpc.StatusCode.NOT_FOUND, "service not found")
status = -1
if request.action == core_pb2.SERVICE_START:
status = session.services.startup_service(node, service, wait=True)
elif request.action == core_pb2.SERVICE_STOP:
status = session.services.stop_service(node, service)
elif request.action == core_pb2.SERVICE_RESTART:
status = session.services.stop_service(node, service)
if not status:
status = session.services.startup_service(node, service, wait=True)
elif request.action == core_pb2.SERVICE_VALIDATE:
status = session.services.validate_service(node, service)
result = False
if not status:
result = True
return core_pb2.ServiceActionResponse(result=result)
def GetWlanConfig(self, request, context):
logging.debug("get wlan config: %s", request)
session = self.get_session(request.session, context)
config = session.mobility.get_model_config(request.id, BasicRangeModel.name)
groups = get_config_groups(config, BasicRangeModel)
return core_pb2.GetWlanConfigResponse(groups=groups)
def SetWlanConfig(self, request, context):
logging.debug("set wlan config: %s", request)
session = self.get_session(request.session, context)
session.mobility.set_model_config(request.id, BasicRangeModel.name, request.config)
return core_pb2.SetWlanConfigResponse(result=True)
def GetEmaneConfig(self, request, context):
logging.debug("get emane config: %s", request)
session = self.get_session(request.session, context)
config = session.emane.get_configs()
groups = get_config_groups(config, session.emane.emane_config)
return core_pb2.GetEmaneConfigResponse(groups=groups)
def SetEmaneConfig(self, request, context):
logging.debug("set emane config: %s", request)
session = self.get_session(request.session, context)
config = session.emane.get_configs()
config.update(request.config)
return core_pb2.SetEmaneConfigResponse(result=True)
def GetEmaneModels(self, request, context):
logging.debug("get emane models: %s", request)
session = self.get_session(request.session, context)
models = []
for model in session.emane.models.keys():
if len(model.split("_")) != 2:
continue
models.append(model)
return core_pb2.GetEmaneModelsResponse(models=models)
def GetEmaneModelConfig(self, request, context):
logging.debug("get emane model config: %s", request)
session = self.get_session(request.session, context)
model = session.emane.models[request.model]
_id = get_emane_model_id(request.id, request.interface)
config = session.emane.get_model_config(_id, request.model)
groups = get_config_groups(config, model)
return core_pb2.GetEmaneModelConfigResponse(groups=groups)
def SetEmaneModelConfig(self, request, context):
logging.debug("set emane model config: %s", request)
session = self.get_session(request.session, context)
_id = get_emane_model_id(request.id, request.interface)
session.emane.set_model_config(_id, request.model, request.config)
return core_pb2.SetEmaneModelConfigResponse(result=True)
def GetEmaneModelConfigs(self, request, context):
logging.debug("get emane model configs: %s", request)
session = self.get_session(request.session, context)
response = core_pb2.GetEmaneModelConfigsResponse()
for node_id, model_config in session.emane.node_configurations.iteritems():
if node_id == -1:
continue
for model_name in model_config.iterkeys():
model = session.emane.models[model_name]
config = session.emane.get_model_config(node_id, model_name)
config_groups = get_config_groups(config, model)
node_configurations = response.configs[node_id]
node_configurations.model = model_name
node_configurations.groups.extend(config_groups)
return response
def SaveXml(self, request, context):
logging.debug("save xml: %s", request)
session = self.get_session(request.session, context)
_, temp_path = tempfile.mkstemp()
session.save_xml(temp_path)
with open(temp_path, "rb") as xml_file:
data = xml_file.read()
return core_pb2.SaveXmlResponse(data=data)
def OpenXml(self, request, context):
logging.debug("open xml: %s", request)
session = self.coreemu.create_session()
session.set_state(EventTypes.CONFIGURATION_STATE)
_, temp_path = tempfile.mkstemp()
with open(temp_path, "wb") as xml_file:
xml_file.write(request.data)
try:
session.open_xml(temp_path, start=True)
return core_pb2.OpenXmlResponse(session=session.id, result=True)
except IOError:
logging.exception("error opening session file")
self.coreemu.delete_session(session.id)
context.abort(grpc.StatusCode.INVALID_ARGUMENT, "invalid xml file")

View file

@ -63,6 +63,19 @@ def get_node_class(node_type):
return _NODE_MAP[node_type]
def get_node_type(node_class):
"""
Retrieve the node type given a node class.
:param class node_class: node class to get type for
:return: node type
:rtype: core.enumerations.NodeTypes
"""
global _NODE_MAP
node_type_map = {v: k for k, v in _NODE_MAP.iteritems()}
return node_type_map.get(node_class)
def is_node(obj, node_types):
"""
Validates if an object is one of the provided node types.

View file

@ -319,7 +319,7 @@ def expand_corepath(pathname, session=None, node=None):
"""
if session is not None:
pathname = pathname.replace("~", "/home/%s" % session.user)
pathname = pathname.replace("%SESSION%", str(session.session_id))
pathname = pathname.replace("%SESSION%", str(session.id))
pathname = pathname.replace("%SESSION_DIR%", session.session_dir)
pathname = pathname.replace("%SESSION_USER%", session.user)

View file

@ -271,7 +271,6 @@ class WirelessModel(ConfigurableOptions):
:param core.session.Session session: core session we are tied to
:param int object_id: object id
:param dict config: values
"""
self.session = session
self.object_id = object_id

View file

@ -648,7 +648,7 @@ class OvsGreTapBridge(OvsNet):
OvsNet.__init__(self, session=session, objid=objid, name=name, policy=policy, start=False)
self.grekey = key
if self.grekey is None:
self.grekey = self.session.session_id ^ self.objid
self.grekey = self.session.id ^ self.objid
self.localnum = None
self.remotenum = None

View file

@ -589,7 +589,7 @@ class GreTapBridge(LxBrNet):
LxBrNet.__init__(self, session=session, objid=objid, name=name, policy=policy, start=False)
self.grekey = key
if self.grekey is None:
self.grekey = self.session.session_id ^ self.objid
self.grekey = self.session.id ^ self.objid
self.localnum = None
self.remotenum = None
self.remoteip = remoteip

View file

@ -46,18 +46,18 @@ class Session(object):
CORE session manager.
"""
def __init__(self, session_id, config=None, mkdir=True):
def __init__(self, _id, config=None, mkdir=True):
"""
Create a Session instance.
:param int session_id: session id
:param int _id: session id
:param dict config: session configuration
:param bool mkdir: flag to determine if a directory should be made
"""
self.session_id = session_id
self.id = _id
# define and create session directory when desired
self.session_dir = os.path.join(tempfile.gettempdir(), "pycore.%s" % self.session_id)
self.session_dir = os.path.join(tempfile.gettempdir(), "pycore.%s" % self.id)
if mkdir:
os.mkdir(self.session_dir)
@ -207,12 +207,12 @@ class Session(object):
state_name = state.name
if self.state == state_value:
logging.info("session(%s) is already in state: %s, skipping change", self.session_id, state_name)
logging.info("session(%s) is already in state: %s, skipping change", self.id, state_name)
return
self.state = state_value
self._state_time = time.time()
logging.info("changing session(%s) to state %s", self.session_id, state_name)
logging.info("changing session(%s) to state %s", self.id, state_name)
self.write_state(state_value)
self.run_hooks(state_value)
@ -397,7 +397,7 @@ class Session(object):
:return:
"""
env = os.environ.copy()
env["SESSION"] = "%s" % self.session_id
env["SESSION"] = "%s" % self.id
env["SESSION_SHORT"] = "%s" % self.short_session_id()
env["SESSION_DIR"] = "%s" % self.session_dir
env["SESSION_NAME"] = "%s" % self.name
@ -562,9 +562,9 @@ class Session(object):
"""
Log information about the session in its current state.
"""
logging.info("session id=%s name=%s state=%s", self.session_id, self.name, self.state)
logging.info("session id=%s name=%s state=%s", self.id, self.name, self.state)
logging.info("file=%s thumbnail=%s node_count=%s/%s",
self.file_name, self.thumbnail, self.get_node_count(), len(self.objects))
self.file_name, self.thumbnail, self.get_node_count(), len(self.objects))
def exception(self, level, source, object_id, text):
"""
@ -579,7 +579,7 @@ class Session(object):
exception_data = ExceptionData(
node=object_id,
session=str(self.session_id),
session=str(self.id),
level=level,
source=source,
date=time.ctime(),
@ -631,10 +631,12 @@ class Session(object):
"""
with self._objects_lock:
count = len([x for x in self.objects if not nodeutils.is_node(x, (NodeTypes.PEER_TO_PEER, NodeTypes.CONTROL_NET))])
count = len([x for x in self.objects.itervalues()
if not nodeutils.is_node(x, (NodeTypes.PEER_TO_PEER, NodeTypes.CONTROL_NET))])
# on Linux, GreTapBridges are auto-created, not part of GUI's node count
count -= len([x for x in self.objects if nodeutils.is_node(x, NodeTypes.TAP_BRIDGE) and not nodeutils.is_node(x, NodeTypes.TUNNEL)])
count -= len([x for x in self.objects.itervalues()
if nodeutils.is_node(x, NodeTypes.TAP_BRIDGE) and not nodeutils.is_node(x, NodeTypes.TUNNEL)])
return count
@ -647,8 +649,8 @@ class Session(object):
# this is called from instantiate() after receiving an event message
# for the instantiation state, and from the broker when distributed
# nodes have been started
logging.info("session(%s) checking if not in runtime state, current state: %s", self.session_id,
coreapi.state_name(self.state))
logging.info("session(%s) checking if not in runtime state, current state: %s", self.id,
coreapi.state_name(self.state))
if self.state == EventTypes.RUNTIME_STATE.value:
logging.info("valid runtime state found, returning")
return
@ -694,7 +696,7 @@ class Session(object):
and links remain.
"""
node_count = self.get_node_count()
logging.info("session(%s) checking shutdown: %s nodes remaining", self.session_id, node_count)
logging.info("session(%s) checking shutdown: %s nodes remaining", self.id, node_count)
shutdown = False
if node_count == 0:
@ -708,7 +710,7 @@ class Session(object):
Return a shorter version of the session ID, appropriate for
interface names, where length may be limited.
"""
ssid = (self.session_id >> 8) ^ (self.session_id & ((1 << 8) - 1))
ssid = (self.id >> 8) ^ (self.id & ((1 << 8) - 1))
return "%x" % ssid
def boot_nodes(self):
@ -961,7 +963,7 @@ class Session(object):
logging.exception("error retrieving control net object")
return
header = "CORE session %s host entries" % self.session_id
header = "CORE session %s host entries" % self.id
if remove:
logging.info("Removing /etc/hosts file entries.")
utils.file_demunge("/etc/hosts", header)