2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
# CORE Python Scripting
|
|
|
|
|
|
|
|
* Table of Contents
|
|
|
|
{:toc}
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
Writing your own Python scripts offers a rich programming environment with
|
|
|
|
complete control over all aspects of the emulation. This chapter provides a
|
|
|
|
brief introduction to scripting. Most of the documentation is available from
|
|
|
|
sample scripts, or online via interactive Python.
|
|
|
|
|
|
|
|
The best starting point is the sample scripts that are included with CORE.
|
|
|
|
If you have a CORE source tree, the example script files can be found under
|
|
|
|
*core/daemon/examples/python/*. When CORE is installed from packages, the example
|
|
|
|
script files will be in */usr/share/core/examples/python/* (or */usr/local/*
|
|
|
|
prefix when installed from source.) For the most part, the example scripts are
|
|
|
|
self-documenting; see the comments contained within the Python code.
|
|
|
|
|
|
|
|
The scripts should be run with root privileges because they create new network
|
|
|
|
namespaces. In general, a CORE Python script does not connect to the CORE
|
|
|
|
daemon, in fact the *core-daemon* is just another Python script that uses
|
|
|
|
the CORE Python modules and exchanges messages with the GUI. To connect the
|
|
|
|
GUI to your scripts, see the included sample scripts that allow for GUI
|
|
|
|
connections.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
Here are the basic elements of a CORE Python script:
|
|
|
|
|
|
|
|
```python
|
2020-05-21 06:14:03 +01:00
|
|
|
"""
|
|
|
|
This is a standalone script to run a small switch based scenario and will not
|
|
|
|
interact with the GUI.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
2018-07-31 20:57:30 +01:00
|
|
|
from core.emulator.coreemu import CoreEmu
|
2020-06-16 20:50:24 +01:00
|
|
|
from core.emulator.data import IpPrefixes
|
2019-06-11 20:05:04 +01:00
|
|
|
from core.emulator.enumerations import EventTypes
|
2020-05-21 06:14:03 +01:00
|
|
|
from core.nodes.base import CoreNode
|
|
|
|
from core.nodes.network import SwitchNode
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
NODES = 2
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
def main():
|
|
|
|
# ip generator for example
|
|
|
|
prefixes = IpPrefixes(ip4_prefix="10.83.0.0/16")
|
|
|
|
|
|
|
|
# create emulator instance for creating sessions and utility methods
|
|
|
|
coreemu = CoreEmu()
|
|
|
|
session = coreemu.create_session()
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
# must be in configuration state for nodes to start, when using "node_add" below
|
|
|
|
session.set_state(EventTypes.CONFIGURATION_STATE)
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
# create switch network node
|
|
|
|
switch = session.add_node(SwitchNode, _id=100)
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
# create nodes
|
|
|
|
for _ in range(NODES):
|
|
|
|
node = session.add_node(CoreNode)
|
2020-06-19 21:28:11 +01:00
|
|
|
iface_data = prefixes.create_iface(node)
|
|
|
|
session.add_link(node.id, switch.id, iface1_data=iface_data)
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-05-21 06:14:03 +01:00
|
|
|
# instantiate session
|
|
|
|
session.instantiate()
|
|
|
|
|
|
|
|
# run any desired logic here
|
|
|
|
|
|
|
|
# shutdown session
|
|
|
|
coreemu.shutdown()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
main()
|
2018-07-31 20:57:30 +01:00
|
|
|
```
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
The above script creates a CORE session having two nodes connected with a
|
|
|
|
switch, Then immediately shutsdown.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
The CORE Python modules are documented with comments in the code. From an
|
|
|
|
interactive Python shell, you can retrieve online help about the various
|
|
|
|
classes and methods; for example *help(CoreNode)* or *help(Session)*.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-04-10 05:33:20 +01:00
|
|
|
> **NOTE:** The CORE daemon *core-daemon* manages a list of sessions and allows
|
2020-04-09 22:34:52 +01:00
|
|
|
the GUI to connect and control sessions. Your Python script uses the same CORE
|
|
|
|
modules but runs independently of the daemon. The daemon does not need to be
|
|
|
|
running for your script to work.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
The session created by a Python script may be viewed in the GUI if certain
|
|
|
|
steps are followed. The GUI has a *File Menu*, *Execute Python script...*
|
|
|
|
option for running a script and automatically connecting to it. Once connected,
|
|
|
|
normal GUI interaction is possible, such as moving and double-clicking nodes,
|
|
|
|
activating Widgets, etc.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
The script should have a line such as the following for running it from the GUI.
|
|
|
|
|
|
|
|
```python
|
|
|
|
if __name__ in ["__main__", "__builtin__"]:
|
|
|
|
main()
|
|
|
|
```
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
A script can add sessions to the core-daemon. A global *coreemu* variable is
|
|
|
|
exposed to the script pointing to the *CoreEmu* object.
|
|
|
|
|
|
|
|
The example below has a fallback to a new CoreEmu object, in the case you would
|
|
|
|
like to run the script standalone, outside of the core-daemon.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
```python
|
|
|
|
coreemu = globals().get("coreemu", CoreEmu())
|
|
|
|
session = coreemu.create_session()
|
|
|
|
```
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
Finally, nodes and networks need to have their coordinates set to something,
|
|
|
|
otherwise they will be grouped at the coordinates *<0, 0>*. First sketching
|
|
|
|
the topology in the GUI and then using the *Export Python script* option may
|
|
|
|
help here.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
```python
|
|
|
|
switch.setposition(x=80,y=50)
|
|
|
|
```
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
A fully-worked example script that you can launch from the GUI is available
|
|
|
|
in the examples directory.
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
## Configuring Services
|
|
|
|
|
|
|
|
Examples setting or configuring custom services for a node.
|
|
|
|
|
|
|
|
```python
|
|
|
|
# create session and node
|
|
|
|
coreemu = CoreEmu()
|
|
|
|
session = coreemu.create_session()
|
|
|
|
|
2020-04-09 22:34:52 +01:00
|
|
|
# create node with custom services
|
2020-06-09 18:45:18 +01:00
|
|
|
options = NodeOptions(services=["ServiceName"])
|
2020-06-19 21:28:11 +01:00
|
|
|
node = session.add_node(CoreNode, options=options)
|
2018-07-31 20:57:30 +01:00
|
|
|
|
|
|
|
# set custom file data
|
2019-04-27 06:07:51 +01:00
|
|
|
session.services.set_service_file(node.id, "ServiceName", "FileName", "custom file data")
|
2018-07-31 20:57:30 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
# Configuring EMANE Models
|
|
|
|
|
|
|
|
Examples for configuring custom emane model settings.
|
|
|
|
|
|
|
|
```python
|
|
|
|
# create session and emane network
|
|
|
|
coreemu = CoreEmu()
|
|
|
|
session = coreemu.create_session()
|
2019-10-23 05:27:31 +01:00
|
|
|
session.set_location(47.57917, -122.13232, 2.00000, 1.0)
|
|
|
|
options = NodeOptions()
|
|
|
|
options.set_position(80, 50)
|
2020-05-21 06:14:03 +01:00
|
|
|
emane_network = session.add_node(EmaneNet, options=options)
|
2018-07-31 20:57:30 +01:00
|
|
|
|
2020-06-09 18:45:18 +01:00
|
|
|
# set custom emane model config defaults
|
|
|
|
session.emane.set_model(emane_network, EmaneIeee80211abgModel)
|
2018-07-31 20:57:30 +01:00
|
|
|
```
|