diff --git a/CHANGELOG.md b/CHANGELOG.md index 836571e8..425f2ae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## 2023-08-01 CORE 9.0.3 + +* Installation + * updated various dependencies +* Documentation + * improved GUI docs to include node interaction and note xhost usage + * \#780 - fixed gRPC examples + * \#787 - complete documentation revamp to leverage mkdocs material + * \#790 - fixed custom emane model example +* core-daemon + * update type hinting to avoid deprecated imports + * updated commands ran within docker based nodes to have proper environment variables + * fixed issue improperly setting session options over gRPC + * \#668 - add fedora sbin path to frr service + * \#774 - fixed pcap configservice + * \#805 - fixed radvd configservice template error +* core-gui + * update type hinting to avoid deprecated imports + * fixed issue allowing duplicate named hook scripts + * fixed issue joining sessions with RJ45 nodes +* utility scripts + * fixed issue in core-cleanup for removing devices + ## 2023-03-02 CORE 9.0.2 * Installation @@ -12,11 +35,10 @@ * fixed issue for LXC nodes to properly use a configured image name and write it to XML * \#742 - fixed issue with bad wlan node id being used * \#744 - fixed issue not properly setting broadcast address - -## core-gui -* fixed sample1.xml to remove SSH service -* fixed emane demo examples -* fixed issue displaying emane configs generally configured for a node +* core-gui + * fixed sample1.xml to remove SSH service + * fixed emane demo examples + * fixed issue displaying emane configs generally configured for a node ## 2022-11-28 CORE 9.0.1 diff --git a/dockerfiles/Dockerfile.ubuntu b/Dockerfile similarity index 56% rename from dockerfiles/Dockerfile.ubuntu rename to Dockerfile index 9762fd05..08f5e548 100644 --- a/dockerfiles/Dockerfile.ubuntu +++ b/Dockerfile @@ -11,9 +11,72 @@ ENV PATH="$PATH:${VENV_PATH}/bin" WORKDIR /opt # install system dependencies + +RUN apt-get update -y && \ + apt-get install -y software-properties-common + +RUN add-apt-repository "deb http://archive.ubuntu.com/ubuntu jammy universe" + RUN apt-get update -y && \ apt-get install -y --no-install-recommends \ + automake \ + bash \ ca-certificates \ + ethtool \ + gawk \ + gcc \ + g++ \ + iproute2 \ + iputils-ping \ + libc-dev \ + libev-dev \ + libreadline-dev \ + libtool \ + nftables \ + python3 \ + python3-pip \ + python3-tk \ + pkg-config \ + tk \ + xauth \ + xterm \ + vim \ + build-essential \ + nano \ + firefox \ + net-tools \ + rsync \ + openssh-server \ + openssh-client \ + vsftpd \ + atftpd \ + atftp \ + mini-httpd \ + lynx \ + tcpdump \ + wireshark \ + iperf \ + iperf3 \ + tshark \ + openssh-sftp-server \ + bind9 \ + bind9-utils \ + openvpn \ + isc-dhcp-server \ + isc-dhcp-client \ + whois \ + ipcalc \ + socat \ + hping3 \ + libgtk-3-0 \ + librest-0.7-0 \ + libgtk-3-common \ + dconf-gsettings-backend \ + libsoup-gnome2.4-1 \ + libsoup2.4-1 \ + dconf-service \ + x11-xserver-utils \ + ftp \ git \ sudo \ wget \ @@ -26,8 +89,8 @@ RUN apt-get update -y && \ unzip \ uuid-dev \ iproute2 \ - iputils-ping \ - tcpdump && \ + vlc \ + iputils-ping && \ apt-get autoremove -y # install core @@ -35,8 +98,7 @@ RUN git clone https://github.com/coreemu/core && \ cd core && \ git checkout ${BRANCH} && \ ./setup.sh && \ - . /root/.bashrc && \ - inv install -v -p ${PREFIX} && \ + PATH=/root/.local/bin:$PATH inv install -v -p ${PREFIX} && \ cd /opt && \ rm -rf ospf-mdr @@ -60,3 +122,5 @@ RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC rm -f protoc-${PROTOC_VERSION}-linux-x86_64.zip WORKDIR /root + +CMD /opt/core/venv/bin/core-daemon diff --git a/README.md b/README.md index b0aa133f..efab2e70 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,107 @@ +# Index +- CORE +- Docker Setup + - Precompiled container image + - Build container image from source + - Adding extra packages + +- Useful commands +- License + # CORE + CORE: Common Open Research Emulator Copyright (c)2005-2022 the Boeing Company. See the LICENSE file included in this distribution. -## About -The Common Open Research Emulator (CORE) is a tool for emulating -networks on one or more machines. You can connect these emulated -networks to live networks. CORE consists of a GUI for drawing -topologies of lightweight virtual machines, and Python modules for -scripting network emulation. +# Docker Setup -## Quick Start -Requires Python 3.9+. More detailed instructions and install options can be found -[here](https://coreemu.github.io/core/install.html). +Here you have 2 choices -### Package Install -Grab the latest deb/rpm from [releases](https://github.com/coreemu/core/releases). +## Precompiled container image + +```bash + +# Start container +sudo docker run -itd --name core -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw --privileged --restart unless-stopped git.olympuslab.net/afonso/core-extra:latest + +``` +## Build container image from source + +```bash +# Clone the repo +git clone https://gitea.olympuslab.net/afonso/core-extra.git + +# cd into the directory +cd core-extra + +# build the docker image +sudo docker build -t core-extra . + +# start container +sudo docker run -itd --name core -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:rw --privileged --restart unless-stopped core-extra -This will install vnoded/vcmd, system dependencies, and CORE within a python -virtual environment at `/opt/core/venv`. -```shell -sudo install -y ./ ``` -Then install OSPF MDR from source: -```shell -git clone https://github.com/USNavalResearchLaboratory/ospf-mdr.git -cd ospf-mdr -./bootstrap.sh -./configure --disable-doc --enable-user=root --enable-group=root \ - --with-cflags=-ggdb --sysconfdir=/usr/local/etc/quagga --enable-vtysh \ - --localstatedir=/var/run/quagga -make -j$(nproc) -sudo make install +### Adding extra packages + +To add extra packages you must modify the Dockerfile and then compile the docker image. +If you install it after starting the container it will, by docker nature, be reverted on the next boot of the container. + +# Useful commands + +I have the following functions on my fish shell +to help me better use core + +THIS ONLY WORKS ON FISH, MODIFY FOR BASH OR ZSH + +```fish + +# RUN CORE GUI +function core + xhost +local:root + sudo docker exec -it core core-gui +end + +# RUN BASH INSIDE THE CONTAINER +function core-bash + sudo docker exec -it core /bin/bash +end + + +# LAUNCH NODE BASH ON THE HOST MACHINE +function launch-term --argument nodename + sudo docker exec -it core xterm -bg black -fg white -fa 'DejaVu Sans Mono' -fs 16 -e vcmd -c /tmp/pycore.1/$nodename -- /bin/bash +end + +#TO RUN ANY OTHER COMMAND +sudo docker exec -it core COMAND_GOES_HERE + ``` -### Script Install -The following should get you up and running on Ubuntu 22.04. This would -install CORE into a python3 virtual environment and install -[OSPF MDR](https://github.com/USNavalResearchLaboratory/ospf-mdr) from source. +## LICENSE -```shell -git clone https://github.com/coreemu/core.git -cd core -# install dependencies to run installation task -./setup.sh -# run the following or open a new terminal -source ~/.bashrc -# Ubuntu -inv install -# CentOS -inv install -p /usr -``` +Copyright (c) 2005-2018, the Boeing Company. -## Documentation & Support -We are leveraging GitHub hosted documentation and Discord for persistent -chat rooms. This allows for more dynamic conversations and the -capability to respond faster. Feel free to join us at the link below. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -* [Documentation](https://coreemu.github.io/core/) -* [Discord Channel](https://discord.gg/AKd7kmP) +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/configure.ac b/configure.ac index c8108f27..4e56507a 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. # this defines the CORE version number, must be static for AC_INIT -AC_INIT(core, 9.0.2) +AC_INIT(core, 9.0.3) # autoconf and automake initialization AC_CONFIG_SRCDIR([netns/version.h.in]) diff --git a/daemon/core/configservices/utilservices/templates/etc/radvd/radvd.conf b/daemon/core/configservices/utilservices/templates/etc/radvd/radvd.conf index 1436f068..d003b4b1 100644 --- a/daemon/core/configservices/utilservices/templates/etc/radvd/radvd.conf +++ b/daemon/core/configservices/utilservices/templates/etc/radvd/radvd.conf @@ -1,5 +1,5 @@ # auto-generated by RADVD service (utility.py) -% for ifname, prefixes in values: +% for ifname, prefixes in ifaces: interface ${ifname} { AdvSendAdvert on; diff --git a/daemon/core/utils.py b/daemon/core/utils.py index 2cfd3605..df00984c 100644 --- a/daemon/core/utils.py +++ b/daemon/core/utils.py @@ -414,18 +414,16 @@ def load_logging_config(config_path: Path) -> None: def run_cmds_threaded( - nodes: list["CoreNode"], - cmds: list[str], + node_cmds: list[tuple["CoreNode", list[str]]], wait: bool = True, shell: bool = False, workers: int = None, ) -> tuple[dict[int, list[str]], list[Exception]]: """ - Run a set of commands in order across a provided set of nodes. Each node will + Run the set of commands for the node provided. Each node will run the commands within the context of a threadpool. - :param nodes: nodes to run commands in - :param cmds: commands to run in nodes + :param node_cmds: list of tuples of nodes and commands to run within them :param wait: True to wait for status, False otherwise :param shell: True to run shell like, False otherwise :param workers: number of workers for threadpool, uses library default otherwise @@ -436,16 +434,16 @@ def run_cmds_threaded( def _node_cmds( _target: "CoreNode", _cmds: list[str], _wait: bool, _shell: bool ) -> list[str]: - outputs = [] + cmd_outputs = [] for _cmd in _cmds: output = _target.cmd(_cmd, wait=_wait, shell=_shell) - outputs.append(output) - return outputs + cmd_outputs.append(output) + return cmd_outputs with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor: futures = [] node_mappings = {} - for node in nodes: + for node, cmds in node_cmds: future = executor.submit(_node_cmds, node, cmds, wait, shell) node_mappings[future] = node futures.append(future) @@ -463,19 +461,17 @@ def run_cmds_threaded( def run_cmds_mp( - nodes: list["CoreNode"], - cmds: list[str], + node_cmds: list[tuple["CoreNode", list[str]]], wait: bool = True, shell: bool = False, workers: int = None, ) -> tuple[dict[int, list[str]], list[Exception]]: """ - Run a set of commands in order across a provided set of nodes. Each node will + Run the set of commands for the node provided. Each node will run the commands within the context of a process pool. This will not work for distributed nodes and throws an exception when encountered. - :param nodes: nodes to run commands in - :param cmds: commands to run in nodes + :param node_cmds: list of tuples of nodes and commands to run within them :param wait: True to wait for status, False otherwise :param shell: True to run shell like, False otherwise :param workers: number of workers for threadpool, uses library default otherwise @@ -486,7 +482,7 @@ def run_cmds_mp( with concurrent.futures.ProcessPoolExecutor(max_workers=workers) as executor: futures = [] node_mapping = {} - for node in nodes: + for node, cmds in node_cmds: node_cmds = [node.create_cmd(x) for x in cmds] if node.server: raise CoreError( diff --git a/daemon/pyproject.toml b/daemon/pyproject.toml index 11e79029..0d1acf7a 100644 --- a/daemon/pyproject.toml +++ b/daemon/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "core" -version = "9.0.2" +version = "9.0.3" description = "CORE Common Open Research Emulator" authors = ["Boeing Research and Technology"] license = "BSD-2-Clause" diff --git a/dockerfiles/Dockerfile.centos b/dockerfiles/Dockerfile.centos index 6a33039c..06654486 100644 --- a/dockerfiles/Dockerfile.centos +++ b/dockerfiles/Dockerfile.centos @@ -13,6 +13,7 @@ WORKDIR /opt # install system dependencies RUN yum -y update && \ yum install -y \ + xterm \ git \ sudo \ wget \ @@ -27,7 +28,8 @@ RUN yum -y update && \ tcpdump \ make && \ yum-builddep -y python3 && \ - yum autoremove -y + yum autoremove -y && \ + yum install -y hostname # install python3.9 RUN wget https://www.python.org/ftp/python/3.9.15/Python-3.9.15.tgz && \ @@ -44,7 +46,7 @@ RUN git clone https://github.com/coreemu/core && \ cd core && \ git checkout ${BRANCH} && \ NO_SYSTEM=1 PYTHON=/usr/local/bin/python3.9 ./setup.sh && \ - . /root/.bashrc && PYTHON=/usr/local/bin/python3.9 inv install -v -p ${PREFIX} --no-python + PATH=/root/.local/bin:$PATH PYTHON=/usr/local/bin/python3.9 inv install -v -p ${PREFIX} --no-python # install emane RUN wget -q https://adjacentlink.com/downloads/emane/emane-1.3.3-release-1.el7.x86_64.tar.gz && \ diff --git a/dockerfiles/Dockerfile.centos-package b/dockerfiles/Dockerfile.centos-package index 5c2366ed..8d4a1296 100644 --- a/dockerfiles/Dockerfile.centos-package +++ b/dockerfiles/Dockerfile.centos-package @@ -11,6 +11,7 @@ WORKDIR /opt # install basic dependencies RUN yum -y update && \ yum install -y \ + xterm \ git \ sudo \ wget \ @@ -30,7 +31,8 @@ RUN yum -y update && \ pkg-config \ make && \ yum-builddep -y python3 && \ - yum autoremove -y + yum autoremove -y && \ + yum install -y hostname # install python3.9 RUN wget https://www.python.org/ftp/python/3.9.15/Python-3.9.15.tgz && \ diff --git a/docs/tutorials/common/grpc.md b/docs/tutorials/common/grpc.md index 71630d38..2a85d7c8 100644 --- a/docs/tutorials/common/grpc.md +++ b/docs/tutorials/common/grpc.md @@ -18,5 +18,5 @@ the remaining steps of a given section. ``` 4. You will be presented with sessions to join, select the one created by the script

- +

diff --git a/docs/tutorials/tutorial1.md b/docs/tutorials/tutorial1.md index 75f13c7c..7bda7e7f 100644 --- a/docs/tutorials/tutorial1.md +++ b/docs/tutorials/tutorial1.md @@ -6,7 +6,7 @@ This tutorial will cover some use cases when using a wired 2 node scenario in CORE.

- +

## Files @@ -46,11 +46,11 @@ between nodes in CORE. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n1** by double clicking it in the GUI * Run the following in **n1** terminal @@ -84,11 +84,11 @@ traffic being sent/received among many other uses. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n1** by double clicking it in the GUI * Open a terminal on **n2** by double clicking it in the GUI @@ -123,20 +123,20 @@ beneficial for understanding how software will behave in adverse conditions. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Right click the link between **n1** and **n2** * Select **Configure**

- +

* Update the loss to **25**

- +

* Open a terminal on **n1** by double clicking it in the GUI * Run the following in **n1** terminal @@ -166,11 +166,11 @@ within the nodes of our scenario. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n1** by double clicking it in the GUI * Run the following in **n1** terminal @@ -216,11 +216,11 @@ using `tail -f` to observe the output of running software. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario_service.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n1** by double clicking it in the GUI * Run the following in **n1** terminal diff --git a/docs/tutorials/tutorial2.md b/docs/tutorials/tutorial2.md index 5455917b..7b82e04e 100644 --- a/docs/tutorials/tutorial2.md +++ b/docs/tutorials/tutorial2.md @@ -30,7 +30,7 @@ XML scenario file, leveraging an NS2 mobility file. * Navigate to and select this tutorials **scenario.xml** file * You can now click play to start the session

- +

* Note that OSPF routing protocol is included in the scenario to provide routes to other nodes, as they are discovered * Double click node **n4** to open a terminal and ping node **n2** @@ -49,7 +49,7 @@ XML scenario file, leveraging an NS2 mobility file. * Right click on the **wlan1** node and select **WLAN Config**, then set delay to 500000

- +

* Using the open terminal for node **n4**, ping **n2** again, expect about 2 seconds delay ```shell @@ -69,7 +69,7 @@ XML scenario file, leveraging an NS2 mobility file. * Right click on the **wlan1** node and select **WLAN Config**, set delay back to 5000 and loss to 10

- +

* Using the open terminal for node **n4**, ping **n2** again, expect to notice considerable loss ```shell @@ -111,7 +111,7 @@ gRPC python script and providing mobility over the gRPC interface. * You will now have joined the already running scenario

- +

## Running Software diff --git a/docs/tutorials/tutorial3.md b/docs/tutorials/tutorial3.md index 362803fc..eaa2a5e6 100644 --- a/docs/tutorials/tutorial3.md +++ b/docs/tutorials/tutorial3.md @@ -71,7 +71,7 @@ file, leveraging an NS2 file for mobility. known and when the routes are discovered, ping will work

- +

## Running with the gRPC Script @@ -94,11 +94,11 @@ This section covers using a gRPC script to create and provide scenario movement. * You will now have joined the already running scenario * In the terminal running the **scenario.py**, hit a key to start motion

- +

* Observe the link between **n3** and **n4** is shown and then as motion continues the link breaks

- +

## Running the Chat App Software @@ -151,5 +151,5 @@ API. * Observe that node 2 moves and continues to move

- +

diff --git a/docs/tutorials/tutorial5.md b/docs/tutorials/tutorial5.md index 7f2d151e..92337717 100644 --- a/docs/tutorials/tutorial5.md +++ b/docs/tutorials/tutorial5.md @@ -18,7 +18,7 @@ This section covers using the saved **scenario.xml** file to get and up and runn * Configure the Windows host VM to have a bridged network adapter

- +

* Make sure the **core-daemon** is running in a terminal ```shell @@ -30,15 +30,15 @@ This section covers using the saved **scenario.xml** file to get and up and runn ``` * Open the **scenario.xml** with the unassigned RJ45 node

- +

* Configure the RJ45 node name to use the bridged interface

- +

* After configuring the RJ45, run the scenario:

- +

* Double click node **n1** to open a terminal and add a route to the Windows host ```shell @@ -97,7 +97,7 @@ This section covers leveraging the gRPC script to get up and running. * Configure the Windows host VM to have a bridged network adapter

- +

* Make sure the **core-daemon** is running in a terminal ```shell @@ -114,7 +114,7 @@ This section covers leveraging the gRPC script to get up and running. ``` * In the **core-gui** connect to the running session that was created

- +

* Double click node **n1** to open a terminal and add a route to the Windows host ```shell diff --git a/docs/tutorials/tutorial6.md b/docs/tutorials/tutorial6.md index 6135d21e..46bb57ac 100644 --- a/docs/tutorials/tutorial6.md +++ b/docs/tutorials/tutorial6.md @@ -31,11 +31,11 @@ This section will cover running this sample tutorial that develops a scenario fi * Create three MDR nodes

- +

* Double click on each node for configuration, click the icon and set it to use the **drone.png** image

- +

* Use **Session -> Options** and set **Control Network 0** to **172.16.0.0./24** @@ -44,30 +44,30 @@ This section will cover running this sample tutorial that develops a scenario fi * Add a WLAN Node * Link the three prior MDR nodes to the WLAN node

- +

* Click play to start the scenario * Observe wireless links being created

- +

* Click stop to end the scenario * Right click the WLAN node and select **Edit -> Hide** * Now you can view the nodes in isolation

- +

### Changing Canvas Background * Click **Canvas -> Wallpaper** to set the background to terrain.png

- +

* Click play to start the scenario again * You now have a scenario with drone icons, terrain background, links displayed and hidden WLAN node

- +

## Adding Mobility @@ -80,7 +80,7 @@ This section will cover running this sample tutorial that develops a scenario fi ``` * Let it run to see the link break as the node 1 drone approches the right side

- +

* Repeat for other nodes, double click on **n2** and **n3** and run the demo.py script ```shell @@ -93,5 +93,5 @@ This section will cover running this sample tutorial that develops a scenario fi * Observe nodes moving in parallel tracks, when the far right is reached, the node will move down and then move to the left. When the far left is reached, the drone will move down and then move to the right.

- +

diff --git a/docs/tutorials/tutorial7.md b/docs/tutorials/tutorial7.md index 89a84555..2cc2f812 100644 --- a/docs/tutorials/tutorial7.md +++ b/docs/tutorials/tutorial7.md @@ -6,7 +6,7 @@ This tutorial will cover basic usage and some concepts one may want to use or leverage when working with and creating EMANE based networks.

- +

For more detailed information on EMANE see the following: @@ -52,11 +52,11 @@ between nodes in CORE. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n2** by double clicking it in the GUI * Run the following in **n2** terminal @@ -90,11 +90,11 @@ traffic being sent/received among many other uses. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n2** by double clicking it in the GUI * Open a terminal on **n3** by double clicking it in the GUI @@ -129,11 +129,11 @@ within the nodes of our scenario. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n2** by double clicking it in the GUI * Run the following in **n2** terminal @@ -179,11 +179,11 @@ using `tail -f` to observe the output of running software. ``` * In the GUI menu bar select **File->Open...**, then navigate to and select **scenario_service.xml**

- +

* You can now click on the **Start Session** button to run the scenario

- +

* Open a terminal on **n2** by double clicking it in the GUI * Run the following in **n2** terminal diff --git a/mkdocs.yml b/mkdocs.yml index c2fbc03c..03504b13 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,7 @@ site_name: CORE Documentation +site_url: https://coreemu.github.io/core +repo_name: coreemu/core +repo_url: https://github.com/coreemu/core use_directory_urls: false theme: name: material