From 8372e2f6229222f4e40d33e2cf98d6aaaa4cc413 Mon Sep 17 00:00:00 2001 From: stevenvanrossem Date: Sat, 16 Jul 2016 23:47:11 +0200 Subject: [PATCH] add docker-compose example --- .../examples/son-monitor_default_topo.py | 100 ++++++++++++++++++ utils/docker/Dockerfile | 24 +++-- utils/docker/docker-compose_son-emu.yml | 19 ++++ utils/docker/entrypoint.sh | 4 +- utils/docker/entrypoint_docker-compose.sh | 68 ++++++++++++ 5 files changed, 202 insertions(+), 13 deletions(-) create mode 100755 src/emuvim/examples/son-monitor_default_topo.py create mode 100755 utils/docker/docker-compose_son-emu.yml create mode 100755 utils/docker/entrypoint_docker-compose.sh diff --git a/src/emuvim/examples/son-monitor_default_topo.py b/src/emuvim/examples/son-monitor_default_topo.py new file mode 100755 index 0000000..29893ae --- /dev/null +++ b/src/emuvim/examples/son-monitor_default_topo.py @@ -0,0 +1,100 @@ +""" +Copyright (c) 2015 SONATA-NFV +ALL RIGHTS RESERVED. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION] +nor the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +This work has been performed in the framework of the SONATA project, +funded by the European Commission under Grant number 671517 through +the Horizon 2020 and 5G-PPP programmes. The authors would like to +acknowledge the contributions of their colleagues of the SONATA +partner consortium (www.sonata-nfv.eu). +""" +""" +A simple topology with two PoPs for the y1 demo story board. + + (dc1) <<-->> s1 <<-->> (dc2) +""" + +import logging +from mininet.log import setLogLevel +from emuvim.dcemulator.net import DCNetwork +from emuvim.api.rest.rest_api_endpoint import RestApiEndpoint +from emuvim.api.sonata import SonataDummyGatekeeperEndpoint +from mininet.node import RemoteController +import signal +import sys + + +logging.basicConfig(level=logging.INFO) + +net = None +cli = None + + +def create_topology1(): + # create topology + net = DCNetwork(controller=RemoteController, monitor=False, enable_learning = False) + dc1 = net.addDatacenter("dc1") + dc2 = net.addDatacenter("dc2") + s1 = net.addSwitch("s1") + net.addLink(dc1, s1, delay="10ms") + net.addLink(dc2, s1, delay="20ms") + + # add the command line interface endpoint to each DC (REST API) + rapi1 = RestApiEndpoint("0.0.0.0", 5001) + rapi1.connectDatacenter(dc1) + rapi1.connectDatacenter(dc2) + # run API endpoint server (in another thread, don't block) + rapi1.start() + + # add the SONATA dummy gatekeeper to each DC + sdkg1 = SonataDummyGatekeeperEndpoint("0.0.0.0", 5000) + sdkg1.connectDatacenter(dc1) + sdkg1.connectDatacenter(dc2) + # run the dummy gatekeeper (in another thread, don't block) + sdkg1.start() + + # start the emulation platform + net.start() + #cli = net.CLI() + #net.stop() + +def exit_gracefully(signum, frame): + """ + 7. At shutdown, we should receive th SIGTERM signal here and shutdown gracefully + """ + # TODO: investigate why this is not called by the sigterm handler + + global net + global cli + + logging.info('Signal handler called with signal {0}'.format(signum)) + net.stop() + + sys.exit() + +def main(): + setLogLevel('info') # set Mininet loglevel + # add the SIGTERM handler (eg. received when son-emu docker container stops) + signal.signal(signal.SIGTERM, exit_gracefully) + create_topology1() + + +if __name__ == '__main__': + main() diff --git a/utils/docker/Dockerfile b/utils/docker/Dockerfile index c40af0a..31da835 100755 --- a/utils/docker/Dockerfile +++ b/utils/docker/Dockerfile @@ -34,17 +34,19 @@ COPY . /son-emu/ RUN apt-get clean -RUN cd /son-emu/ansible \ - && ansible-playbook install.yml \ - && cd /son-emu \ - # we need to reset the __pycache__ for correct test discovery - && rm -rf src/emuvim/test/__pycache__ \ - && rm -rf src/emuvim/test/unittests/__pycache__ \ - && rm -rf src/emuvim/test/integrationtests/__pycache__ \ - && python setup.py install \ - && echo 'Done' +WORKDIR /son-emu/ansible +RUN ansible-playbook install.yml + +WORKDIR /son-emu +# we need to reset the __pycache__ for correct test discovery +RUN rm -rf src/emuvim/test/__pycache__ +RUN rm -rf src/emuvim/test/unittests/__pycache__ +RUN rm -rf src/emuvim/test/integrationtests/__pycache__ +RUN python setup.py install +RUN echo 'Done' + ENTRYPOINT ["/son-emu/utils/docker/entrypoint.sh"] -# dummy GK, zerorpc, DCNetwork zerorpc, cAdvisor -EXPOSE 5000 4242 5151 8090 +# dummy GK, zerorpc, DCNetwork zerorpc, cAdvisor, restAPI +EXPOSE 5000 4242 5151 8090 5001 diff --git a/utils/docker/docker-compose_son-emu.yml b/utils/docker/docker-compose_son-emu.yml new file mode 100755 index 0000000..4e39e32 --- /dev/null +++ b/utils/docker/docker-compose_son-emu.yml @@ -0,0 +1,19 @@ +version: '2' +services: + + son-emu: + image: registry.sonata-nfv.eu:5000/son-emu + container_name: son-emu + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + network_mode: "host" + pid: "host" + privileged: true + ports: + #REST api + - "5001:5001" + entrypoint: + - "/son-emu/utils/ci/entrypoint_docker-compose.sh" + command: [python, src/emuvim/examples/son-monitor_default_topo.py] + + diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index 1820515..4349efd 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -6,7 +6,7 @@ set -x # this cannot be done from the Dockerfile since we have the socket not mounted during build # this image is needed for the monitoring in son-emu -echo 'Pulling the "google/cadvisor" image ... please wait' -docker pull 'google/cadvisor' +#echo 'Pulling the "google/cadvisor" image ... please wait' +#docker pull 'google/cadvisor' exec /containernet/util/docker/entrypoint.sh $* diff --git a/utils/docker/entrypoint_docker-compose.sh b/utils/docker/entrypoint_docker-compose.sh new file mode 100755 index 0000000..421444e --- /dev/null +++ b/utils/docker/entrypoint_docker-compose.sh @@ -0,0 +1,68 @@ +#! /bin/bash -e + +# docker stop trap signals +# https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86#.5d6q01x7q + +pid=0 +command="" +term_recvd=0 + +# send SIGTERM also to the executed command in the docker container (the containernet topology) +# SIGTERM-handler +function term_handler() { + echo $command + pid=$(pgrep -f "$command" | sed -n 1p) + + pid="$!" + # avoid that the process triggers its own handler by sending sigterm + if [ $pid -ne 0 ] && [ $term_recvd -eq 0 ]; then + echo "sigterm received" + echo $pid + term_recvd=1 + kill -SIGTERM "$pid" + fi + + wait "$pid" + + # do some manual cleanup + # remove all containers started by son-emu + docker ps -a -q --filter="name=mn.*" | xargs -r docker rm -f + # cleanup remaining mininet + mn -c + + sleep 5 + exit 143; # 128 + 15 -- SIGTERM +} + +# setup handlers +# on callback, kill the last background process, which is `tail -f /dev/null` and execute the specified handler +trap 'term_handler' SIGTERM + + +service openvswitch-switch start + +if [ ! -S /var/run/docker.sock ]; then + echo 'Error: the Docker socket file "/var/run/docker.sock" was not found. It should be mounted as a volume.' + exit 1 +fi + +# this cannot be done from the Dockerfile since we have the socket not mounted during build +echo 'Pulling the "ubuntu:trusty" image ... please wait' +docker pull 'ubuntu:trusty' + +echo "Welcome to Containernet running within a Docker container ..." + +if [[ $# -eq 0 ]]; then + exec /bin/bash +else + #remember command to send it also the SIGTERM via the handler + command=$* + echo $command + exec $* & + # wait indefinetely + while true + do + sleep 1 + done + echo "done" +fi -- 2.17.1