diff options
Diffstat (limited to 'framework/src/onos/tools')
273 files changed, 14182 insertions, 0 deletions
diff --git a/framework/src/onos/tools/build/conf/pom.xml b/framework/src/onos/tools/build/conf/pom.xml new file mode 100644 index 00000000..e4f8e9dc --- /dev/null +++ b/framework/src/onos/tools/build/conf/pom.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-base</artifactId> + <version>1</version> + </parent> + + <groupId>org.onosproject</groupId> + <artifactId>onos-build-conf</artifactId> + <version>1.0</version> + <description>Various ONOS build settings</description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + +</project> + diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml new file mode 100644 index 00000000..2908c891 --- /dev/null +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml @@ -0,0 +1,295 @@ +<?xml version="1.0"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<!DOCTYPE module PUBLIC + "-//Puppy Crawl//DTD Check Configuration 1.3//EN" + "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> + + +<!-- + + Checkstyle configuration that checks the sun coding conventions from: + + - the Java Language Specification at + http://java.sun.com/docs/books/jls/second_edition/html/index.html + + - the Sun Code Conventions at http://java.sun.com/docs/codeconv/ + + - the Javadoc guidelines at + http://java.sun.com/j2se/javadoc/writingdoccomments/index.html + + - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html + + - some best practices + + Checkstyle is very configurable. Be sure to read the documentation at + http://checkstyle.sf.net (or in your downloaded distribution). + + Most Checks are configurable, be sure to consult the documentation. + + To completely disable a check, just comment it out or delete it from the file. + + Finally, it is worth reading the documentation. + +--> + + +<!-- + The default severity setting in checkstyle is 'error', so some + of the rules below are configured to change the severity to + 'warning'. Over time, these 'warning' settings should be + removed as more of the ONOS source code is modified to + follow the recommended rules. +--> + + + +<module name="Checker"> + <!-- + If you set the basedir property below, then all reported file + names will be relative to the specified directory. See + http://checkstyle.sourceforge.net/5.x/config.html#Checker + + <property name="basedir" value="${basedir}"/> + --> + <!-- Checks that a package-info.java file exists for each package. --> + <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage --> + <!-- ONOS does not currently supply package level Javadoc information + in package-info files --> + <!-- <module name="JavadocPackage"/> --> + + <!-- Checks whether files end with a new line. --> + <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile --> + <module name="NewlineAtEndOfFile"/> + + <!-- Checks that property files contain the same keys. --> + <!-- See http://checkstyle.sf.net/config_misc.html#Translation --> + <module name="Translation"/> + + <!-- Checks for Size Violations. --> + <!-- See http://checkstyle.sf.net/config_sizes.html --> + <module name="FileLength"/> + + <!-- Checks for whitespace --> + <!-- See http://checkstyle.sf.net/config_whitespace.html --> + <module name="FileTabCharacter"/> + + <!-- Miscellaneous other checks. --> + <!-- See http://checkstyle.sf.net/config_misc.html --> + <module name="RegexpSingleline"> + <property name="format" value="\s+$"/> + <property name="minimum" value="0"/> + <property name="maximum" value="0"/> + <property name="message" value="Line has trailing spaces."/> + </module> + + <!-- Checks for Headers --> + <!-- See http://checkstyle.sf.net/config_header.html --> + <!-- <module name="Header"> --> + <!-- <property name="headerFile" value="${checkstyle.header.file}"/> --> + <!-- <property name="fileExtensions" value="java"/> --> + <!-- </module> --> + + <module name="SuppressionCommentFilter"> + <property name="offCommentFormat" value="(CHECKSTYLE\:OFF|Generated by the protocol buffer compiler.)"/> + <property name="onCommentFormat" value="CHECKSTYLE:ON"/> + </module> + + <module name="SuppressWithNearbyCommentFilter"> + <property name="commentFormat" value="CHECKSTYLE IGNORE THIS LINE" /> + <property name="checkFormat" value=".*" /> + <property name="influenceFormat" value="0" /> + </module> + + <!-- Example: // CHECKSTYLE IGNORE FinalClass FOR NEXT 1 LINES --> + <module name="SuppressWithNearbyCommentFilter"> + <property name="commentFormat" value="CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES"/> + <property name="checkFormat" value="$1"/> + <property name="influenceFormat" value="$2"/> + </module> + + <module name="TreeWalker"> + + <module name="FileContentsHolder"/> + <!-- Checks for Javadoc comments. --> + <!-- See http://checkstyle.sf.net/config_javadoc.html --> + <module name="JavadocMethod"> + <property name="severity" value="warning"/> + <property name="allowUndeclaredRTE" value="true"/> + </module> + <module name="JavadocType"> + <property name="severity" value="warning"/> + </module> + <module name="JavadocVariable"> + <!-- Suppress check for private member Javadocs. + Possibly revist fixing these. --> + <property name="scope" value="public"/> + <property name="severity" value="warning"/> + </module> + <module name="JavadocStyle"/> + <!-- @author tag should not be used --> + <module name="WriteTag"> + <property name="tag" value="@author"/> + <property name="tagFormat" value="\S"/> + <property name="severity" value="ignore"/> + <property name="tagSeverity" value="error"/> + </module> + + + <!-- Checks for Naming Conventions. --> + <!-- See http://checkstyle.sf.net/config_naming.html --> + <module name="ConstantName"> + <!-- ONOS allows the name "log" for static final Loggers --> + <property name="format" + value="^log$|^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/> + </module> + <module name="LocalFinalVariableName"/> + + <module name="LocalVariableName"/> + + <module name="MemberName"/> + <module name="MethodName"/> + <module name="PackageName"/> + <module name="ParameterName"/> + <module name="StaticVariableName"/> + <module name="TypeName"/> + + <!-- Checks for imports --> + <!-- See http://checkstyle.sf.net/config_import.html --> + <module name="AvoidStarImport"> + <property name="allowStaticMemberImports" value="true"/> + </module> + <module name="IllegalImport"/> + <!-- defaults to sun.* packages --> + <module name="RedundantImport"/> + <module name="UnusedImports"/> + + + <!-- Checks for Size Violations. --> + <!-- See http://checkstyle.sf.net/config_sizes.html --> + <module name="LineLength"> + <!-- ONOS standard usage is 80 columns, but we allow up + to 120 to not break the build. --> + <property name="max" value="120"/> + <property name="ignorePattern" value="^import"/> + </module> + <module name="MethodLength"> + <property name="max" value="200"/> + </module> + + <module name="ParameterNumber"> + <property name="max" value="15"/> + <property name="tokens" value="CTOR_DEF"/> + </module> + <!-- Checks for whitespace --> + <!-- See http://checkstyle.sf.net/config_whitespace.html --> + <module name="EmptyForIteratorPad"/> + <module name="GenericWhitespace"/> + <module name="MethodParamPad"/> + <module name="NoWhitespaceAfter"/> + <module name="NoWhitespaceBefore"/> + + <!-- Disabled for ONOS. Default rules specify undesired behavior for the '?' operator --> + <!-- <module name="OperatorWrap"/> --> + <module name="ParenPad"/> + <module name="TypecastParenPad"/> + <module name="WhitespaceAfter"/> + <module name="WhitespaceAround"> + <property name="allowEmptyConstructors" value="true"/> + <property name="allowEmptyMethods" value="true"/> + </module> + + + + <!-- Modifier Checks --> + <!-- See http://checkstyle.sf.net/config_modifiers.html --> + <module name="ModifierOrder"/> + + <!-- Disabled for ONOS to allow use of public --> + <!-- modifiers in interfaces. --> + <!-- <module name="RedundantModifier"/> --> + + + <!-- Checks for blocks. You know, those {}'s --> + <!-- See http://checkstyle.sf.net/config_blocks.html --> + <module name="AvoidNestedBlocks"> + <!-- ONOS alows declarations inside of switch case blocks --> + <property name="allowInSwitchCase" value="true"/> + </module> + <module name="EmptyBlock"/> + <module name="LeftCurly"/> + <module name="NeedBraces"/> + <module name="RightCurly"/> + + <!-- Checks for common coding problems --> + <!-- See http://checkstyle.sf.net/config_coding.html --> + <!-- ONOS allows conditional operators --> + <!-- <module name="AvoidInlineConditionals"/> --> + <module name="EmptyStatement"/> + <module name="EqualsHashCode"/> + + <module name="HiddenField"> + <property name="ignoreSetter" value="true"/> + <property name="ignoreConstructorParameter" value="true"/> + </module> + + <module name="IllegalInstantiation"/> + <module name="InnerAssignment"/> + + <!-- Many violations of this rule present, revist in a + subsequent round of cleanups --> + <!-- <module name="MagicNumber"/> --> + <module name="MissingSwitchDefault"/> + + <module name="RedundantThrows"> + <property name="allowSubclasses" value="true"/> + </module> + + <module name="SimplifyBooleanExpression"/> + <module name="SimplifyBooleanReturn"/> + + <!-- Checks for class design --> + <!-- See http://checkstyle.sf.net/config_design.html --> + <!-- ONOS produces many warnings of this type. + Fixing all of these is outside the scope of the current cleanup. --> + <!-- <module name="DesignForExtension"/> --> + <module name="FinalClass"/> + + <module name="HideUtilityClassConstructor"/> + + <module name="InterfaceIsType"/> + + <module name="VisibilityModifier"> + <property name="severity" value="warning"/> + </module> + + + + <!-- Miscellaneous other checks. --> + <!-- See http://checkstyle.sf.net/config_misc.html --> + <module name="ArrayTypeStyle"/> + + <!-- Many violations of this rule currently, too many to fix + in the current cleanup. --> + <!-- <module name="FinalParameters"/> --> + <!-- ONOS allows TODO markers in checked in source code --> + <!-- <module name="TodoComment"/> --> + <module name="UpperEll"/> + + + </module> + + </module> diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/findbugs-suppressions.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/findbugs-suppressions.xml new file mode 100644 index 00000000..2ebfa1de --- /dev/null +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/findbugs-suppressions.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<FindBugsFilter> + + <!-- False positives on calls to CompletableFuture methods with a null + parameter --> + <Match> + <Class name="~org\.onosproject\.store\.service\.impl\..*" /> + <Bug pattern="NP_NONNULL_PARAM_VIOLATION" /> + </Match> + + <!-- Filter out testing application --> + <Match> + <Class name="~org\.onosproject\.foo\..*" /> + </Match> + +</FindBugsFilter> diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/pmd.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/pmd.xml new file mode 100644 index 00000000..68d0b219 --- /dev/null +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/pmd.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + name="ONOS Rules" + xmlns="http://pmd.sf.net/ruleset/1.0.0" + xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd" + xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" > + + <description>ONOS PMD rules</description> + + <rule ref="rulesets/java/unnecessary.xml" > + <exclude name="UselessParentheses" /> + </rule> + <rule ref="rulesets/java/basic.xml"> + <exclude name="EmptyCatchBlock"/> + </rule> + <rule ref="rulesets/java/basic.xml/EmptyCatchBlock"> + <properties> + <property name="allowCommentedBlocks" value="true"/> + </properties> + </rule> + <rule ref="rulesets/java/unusedcode.xml"> + <!-- Explicit public keyword in interface methods is acceptable --> + <exclude name="UnusedModifier" /> + </rule> + <rule ref="rulesets/java/imports.xml"/> + <rule ref="rulesets/java/optimizations.xml"> + <exclude name="LocalVariableCouldBeFinal" /> + <exclude name="MethodArgumentCouldBeFinal" /> + <exclude name="AvoidInstantiatingObjectsInLoops" /> + </rule> + + <rule ref="rulesets/java/strings.xml"> + <exclude name="AvoidDuplicateLiterals" /> + </rule> + <rule ref="rulesets/java/braces.xml"/> + <rule ref="rulesets/java/naming.xml"> + <exclude name="AvoidInstantiatingObjectsInLoops" /> + <exclude name="ShortClassName" /> + <exclude name="ShortMethodName" /> + <exclude name="ShortVariable" /> + <exclude name="LongVariable" /> + </rule> + <rule ref="rulesets/java/naming.xml/VariableNamingConventions"> + <properties> + <!-- ONOS allows the name "log" for static final Loggers --> + <property name="violationSuppressRegex" value=".*'log'.*"/> + </properties> + </rule> + + <rule ref="rulesets/java/clone.xml"/> + <rule ref="rulesets/java/strictexception.xml"/> + <rule ref="rulesets/java/design.xml"> + <exclude name="GodClass" /> + </rule> + <rule ref="rulesets/java/coupling.xml"> + <exclude name="LawOfDemeter" /> + <exclude name="ExcessiveImports" /> + <!-- Suppress Removed misconfigured rule warning --> + <exclude name="LoosePackageCoupling" /> + </rule> +</ruleset> + diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/suppressions.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/suppressions.xml new file mode 100644 index 00000000..a71d941f --- /dev/null +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/suppressions.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> + +<suppressions> + + <suppress files="org.apache.karaf.branding.*" checks="[a-zA-Z0-9]*"/> + + <suppress files=".*" checks="FinalParametersCheck"/> + <suppress files=".*" checks="MagicNumbersCheck"/> + <suppress files=".*" checks="DesignForExtensionCheck"/> + <suppress files=".*" checks="TodoCommentCheck"/> + <suppress files=".*" checks="AvoidInlineConditionalsCheck"/> + <suppress files=".*" checks="OperatorWrapCheck"/> + <suppress files=".*" checks="HiddenField"/> + <suppress files=".java" checks="NewlineAtEndOfFile"/> + +</suppressions> diff --git a/framework/src/onos/tools/build/docker/Dockerfile b/framework/src/onos/tools/build/docker/Dockerfile new file mode 100644 index 00000000..fd61ad86 --- /dev/null +++ b/framework/src/onos/tools/build/docker/Dockerfile @@ -0,0 +1,56 @@ +FROM debian +MAINTAINER Ali Al-Shabibi <ali@onlab.us> + +# Add Java 8 repository +ENV DEBIAN_FRONTEND noninteractive +RUN echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \ + echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \ + echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 + +# Set the environment variables +ENV HOME /root +ENV JAVA_HOME /usr/lib/jvm/java-8-oracle +ENV ONOS_ROOT /src/onos +ENV KARAF_VERSION 3.0.3 +ENV KARAF_ROOT /root/onos/apache-karaf-3.0.3 +ENV KARAF_LOG /root/onos/apache-karaf-3.0.3/data/log/karaf.log +ENV BUILD_NUMBER docker +ENV PATH $PATH:$KARAF_ROOT/bin + +#Download and Build ONOS +WORKDIR /src +RUN apt-get update && apt-get install -y maven git curl oracle-java8-installer oracle-java8-set-default && \ + git clone https://github.com/opennetworkinglab/onos.git && cd onos && \ + mkdir -p /root/Downloads && \ + mvn clean install && \ + tools/build/onos-package && \ + rm -rf /root/.m2 && cd .. && \ + rm -rf onos && \ + apt-get remove --purge -y `apt-mark showauto` && \ + apt-get install oracle-java8-set-default -y && \ + apt-get clean && apt-get purge -y && apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* && \ + rm -rf /var/cache/oracle-jdk8-installer && \ + rm -rf /root/Downloads + +# Change to /root directory +WORKDIR /root + +#Install ONOS +RUN mkdir onos && \ + mv /tmp/onos-*.docker.tar.gz . && \ + tar -xf onos-*.docker.tar.gz -C onos --strip-components=1 && \ + rm -rf onos-*.docker.tar.gz + + +# Ports +# 6633 - OpenFlow +# 8181 - GUI +# 8101 - ONOS CLI +# 9876 - ONOS CLUSTER COMMUNICATION +EXPOSE 6633 8181 8101 9876 + +# Get ready to run command +WORKDIR /root/onos +ENTRYPOINT ["./bin/onos-service"] diff --git a/framework/src/onos/tools/build/envDefaults b/framework/src/onos/tools/build/envDefaults new file mode 100644 index 00000000..57c1f677 --- /dev/null +++ b/framework/src/onos/tools/build/envDefaults @@ -0,0 +1,51 @@ +# Environmental defaults for ONOS build, package and test + +# Root of the ONOS source tree +export ONOS_ROOT=${ONOS_ROOT:-~/onos} + +# M2 repository and Karaf gold bits +export M2_REPO=${M2_REPO:-~/.m2/repository} +export KARAF_VERSION=${KARAF_VERSION:-3.0.3} +export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-$KARAF_VERSION.zip} +export KARAF_TAR=${KARAF_TAR:-~/Downloads/apache-karaf-$KARAF_VERSION.tar.gz} +export KARAF_DIST=$(basename $KARAF_ZIP .zip) + +# Add ONOS-specific directories to the exectable PATH +export PATH="$PATH:$ONOS_ROOT/tools/dev/bin:$ONOS_ROOT/tools/test/bin" +export PATH="$PATH:$ONOS_ROOT/tools/build" + +# Fallback build number us derived from from the user name & time +export BUILD_NUMBER=${BUILD_NUMBER:-$(id -un)~$(date +'%Y/%m/%d@%H:%M')} + +# ONOS Version and onos.tar.gz staging environment +export ONOS_POM_VERSION="1.3.0-SNAPSHOT" +export ONOS_VERSION=${ONOS_VERSION:-1.3.0.$BUILD_NUMBER} + +# ONOS production bits (onos.tar.gz, onos.zip, onos.deb, onos.rpm) staging environment +export ONOS_BITS=onos-${ONOS_VERSION%~*} +export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp} +export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS +export ONOS_DEB_ROOT=$ONOS_STAGE_ROOT/deb +export ONOS_DEB=$ONOS_STAGE.deb +export ONOS_RPM_ROOT=$ONOS_STAGE_ROOT/rpm +export ONOS_RPM=$ONOS_STAGE.rpm +export ONOS_RPM_VERSION=${ONOS_POM_VERSION//-/.} +export ONOS_TAR=$ONOS_STAGE.tar.gz +export ONOS_ZIP=$ONOS_STAGE.zip + +# ONOS test bits (onos-test.tar.gz) staging environment +export ONOS_TEST_BITS=onos-test-${ONOS_VERSION%~*} +export ONOS_TEST_STAGE_ROOT=${ONOS_TEST_STAGE_ROOT:-/tmp} +export ONOS_TEST_STAGE=$ONOS_STAGE_ROOT/$ONOS_TEST_BITS +export ONOS_TEST_TAR=$ONOS_TEST_STAGE.tar.gz + +# Defaults for ONOS testing using remote machines. +# if [ -n "${ONOS_CELL}" -a -f $ONOS_ROOT/tools/test/cells/${ONOS_CELL} ]; then +# . $ONOS_ROOT/tools/test/cells/${ONOS_CELL} +# fi +export ONOS_INSTALL_DIR="/opt/onos" # Installation directory on remote +export OCI="${OCI:-192.168.56.101}" # ONOS Controller Instance +export ONOS_USER="${ONOS_USER:-sdn}" # ONOS user on remote system +export ONOS_GROUP="${ONOS_GROUP:-sdn}" # ONOS group on remote system +export ONOS_PWD="rocks" # ONOS user password on remote system +export ONOS_SCENARIOS=$ONOS_ROOT/tools/test/scenarios diff --git a/framework/src/onos/tools/build/onos-build b/framework/src/onos/tools/build/onos-build new file mode 100755 index 00000000..b9c752e8 --- /dev/null +++ b/framework/src/onos/tools/build/onos-build @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Builds the ONOS from source. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +cd $ONOS_ROOT && mvn clean install "$@" diff --git a/framework/src/onos/tools/build/onos-build-docs b/framework/src/onos/tools/build/onos-build-docs new file mode 100755 index 00000000..93a73c14 --- /dev/null +++ b/framework/src/onos/tools/build/onos-build-docs @@ -0,0 +1,44 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Builds the ONOS Java API docs. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +apidocs=onos-apidocs-${ONOS_VERSION%~*} + +function expandList { + list=""; + while read line; do + [ -n "$line" ] && list="$list:$line" + done < $1 + echo "${list#:*}" +} + +function processPom { + cp $1 aux-$1 + egrep '@[a-zA-Z0-9.-]+' $1 | sed 's:^[^@]*@::g' | sed 's:</.*$::g' | while read line; do + packages="$(expandList $line)" + sed "s/@$line/$packages/" aux-$1 > aux-$1.aux + mv aux-$1.aux aux-$1 + done +} + +set -e + +trap "rm aux-internal.xml aux-external.xml 2>/dev/null" EXIT +rm -fr $ONOS_ROOT/docs/target + +cd $ONOS_ROOT/docs +processPom external.xml +mvn -f aux-external.xml javadoc:aggregate + +cd target && mv site/apidocs $apidocs +tar zcf $apidocs.tar.gz $apidocs && cp $apidocs.tar.gz /tmp + +cd $ONOS_ROOT/docs +processPom internal.xml +mvn -f aux-internal.xml javadoc:aggregate diff --git a/framework/src/onos/tools/build/onos-change-version b/framework/src/onos/tools/build/onos-change-version new file mode 100755 index 00000000..a7117429 --- /dev/null +++ b/framework/src/onos/tools/build/onos-change-version @@ -0,0 +1,56 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Changes ONOS version in POM files, and other release artifacts. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +export NEW_VERSION=$1 +[ -z "$NEW_VERSION" ] && echo "New ONOS version not specified" && exit 1 + +export NEW_VERSION_SHORT=${NEW_VERSION%-SNAPSHOT} + +cd $ONOS_ROOT + +# Augment the version of the main pom and the modules nested underneath. +mvn versions:set -DnewVersion=$NEW_VERSION versions:commit + +# Augment the version of the Java API pom files and the overview.html file. +for pom in docs/internal.xml docs/external.xml; do + sed -i "" -E "1,/<version>/s/<version>[^<]*</<version>$NEW_VERSION</g" $pom + sed -i "" -E "1,/<doctitle>/s/<doctitle>ONOS Java API[^<]*</<doctitle>ONOS Java API ($NEW_VERSION)</g" $pom +done + +# Augment the version in envDefaults, onos.py and archetypes test +sed -i "" -E "s/ONOS_VERSION:-[^$]*/ONOS_VERSION:-$NEW_VERSION_SHORT./" $ONOS_ROOT/tools/build/envDefaults +sed -i "" -E "s/features\/.*\/xml/features\/$NEW_VERSION\/xml/" $ONOS_ROOT/tools/test/topos/onos.py +sed -i "" -E "s/ -Dversion=.*\"/ -Dversion=$NEW_VERSION\"/" $ONOS_ROOT/tools/test/bin/onos-archetypes-test +sed -i "" -E "s/ONOS_POM_VERSION=.*\"/ONOS_POM_VERSION=\"$NEW_VERSION\"/" $ONOS_ROOT/tools/build/envDefaults + +# Augment the version in jdvue/bin and stc/bin +sed -i "" -E "s/VER=.*/VER=$NEW_VERSION/" $ONOS_ROOT/utils/jdvue/bin/jdvue +sed -i "" -E "s/VER=.*/VER=$NEW_VERSION/" $ONOS_ROOT/utils/stc/bin/stc +sed -i "" -E "s/VER=.*/VER=$NEW_VERSION/" $ONOS_ROOT/tools/test/bin/stc + +# Augment fallback version in CoreManager +sed -i "" -E "s/Version\.version\(\"[^\"]*\"\)/Version.version(\"$NEW_VERSION\")/" \ + $ONOS_ROOT/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java + +# Augment the version in archetypes tree. +mvn -f tools/package/archetypes/pom.xml versions:set -DnewVersion=$NEW_VERSION versions:commit +for atype in api bundle cli ui; do + pom="tools/package/archetypes/$atype/src/main/resources/archetype-resources/pom.xml" + sed -i "" -E "1,/<onos.version>/s/<onos.version>[^<]*</<onos.version>$NEW_VERSION</g" $pom +done +sed -i "" -E "s/-DarchetypeVersion=[^\"]*/-DarchetypeVersion=$NEW_VERSION/g" $ONOS_ROOT/tools/test/bin/onos-archetypes-test + +# Augment the version cord-gui +perl -i -0pe "s#<artifactId>cord-gui<.*\n.*version>#<artifactId>cord-gui</artifactId>\n <version>$NEW_VERSION</version>#" $ONOS_ROOT/apps/demo/cord-gui/pom.xml +sed -i "" -E "s#demo/cord-gui/target/cord-gui-.*\.war#demo/cord-gui/target/cord-gui-$NEW_VERSION.war#" $ONOS_ROOT/apps/demo/cord-gui/src/scripts/pullwar.sh +sed -i "" -E "s#CORD=./cord-gui-.*\.war#CORD=./cord-gui-$NEW_VERSION.war#" $ONOS_ROOT/apps/demo/cord-gui/src/scripts/run.me + +# Augment the acl app +sed -i "" -E "s/<onos.version>[^<]*</<onos.version>$NEW_VERSION</g" $ONOS_ROOT/apps/acl/pom.xml diff --git a/framework/src/onos/tools/build/onos-package b/framework/src/onos/tools/build/onos-package new file mode 100755 index 00000000..8f6127da --- /dev/null +++ b/framework/src/onos/tools/build/onos-package @@ -0,0 +1,210 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Packages ONOS distributable into onos.tar.gz, onos.zip or a deb file +# ----------------------------------------------------------------------------- + +set -e + +# Build the staging directory used to produce the packages +function build_stage_dir() { + # Make sure we have the original apache karaf bits first + [ ! -d $M2_REPO ] && echo "M2 repository $M2_REPO not found" && exit 1 + [ -d $ONOS_STAGE ] && echo "ONOS stage $ONOS_STAGE already exists" && exit 1 + + # Create the stage directory and warp into it + mkdir -p $ONOS_STAGE + cd $ONOS_STAGE + + # Check if Apache Karaf bits are available and if not, fetch them. + if [ ! -f $KARAF_ZIP -a ! -f $KARAF_TAR ]; then + echo "Downloading $KARAF_TAR..." + curl -sL http://downloads.onosproject.org/third-party/apache-karaf-$KARAF_VERSION.tar.gz > $KARAF_TAR + fi + [ ! -f $KARAF_ZIP -a ! -f $KARAF_TAR ] && \ + echo "Apache Karaf bits $KARAF_ZIP or $KARAF_TAR not found" && exit 1 + + # Unroll the Apache Karaf bits, prune them and make ONOS top-level directories. + [ -f $KARAF_ZIP ] && unzip -q $KARAF_ZIP && rm -rf $ONOS_STAGE/$KARAF_DIST/demos + [ -f $KARAF_TAR ] && tar zxf $KARAF_TAR && rm -rf $ONOS_STAGE/$KARAF_DIST/demos + mkdir bin + + # Stage the ONOS admin scripts and patch in Karaf service wrapper extras + cp -r $ONOS_ROOT/tools/package/bin . + cp -r $ONOS_ROOT/tools/package/debian $ONOS_STAGE/debian + cp -r $ONOS_ROOT/tools/package/etc/* $ONOS_STAGE/$KARAF_DIST/etc + + # Stage all builtin ONOS apps for factory install + onos-stage-apps $ONOS_STAGE/apps $ONOS_STAGE/$KARAF_DIST/system + + # Mark the org.onosproject.drivers app active by default + touch $ONOS_STAGE/apps/org.onosproject.drivers/active + + # Patch-in proper Karaf version into the startup script + sed "s/\$KARAF_VERSION/$KARAF_VERSION/g" \ + $ONOS_ROOT/tools/package/bin/onos-service > bin/onos-service + sed "s/\$KARAF_VERSION/$KARAF_VERSION/g" \ + $ONOS_ROOT/tools/package/bin/onos-client > bin/onos + chmod a+x bin/onos-service bin/onos + + # Stage the ONOS bundles, but only those that match the version + mkdir -p $ONOS_STAGE/$KARAF_DIST/system/org/onosproject + find $M2_REPO/org/onosproject -type f -path "*/$ONOS_POM_VERSION/*" \ + -name '*.jar' -o -name '*.pom' -o -name '*-features.xml' \ + | grep -v -Ee '-tests.jar|-[0-9]{8}.[0-9]{6}-' \ + | while read src; do + dst=$ONOS_STAGE/$KARAF_DIST/system/${src#$M2_REPO/*} + mkdir -p $(dirname $dst) + cp $src $dst + done + + # ONOS Patching ---------------------------------------------------------------- + + # Patch the Apache Karaf distribution file to add ONOS features repository + perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onosproject/onos-features/$ONOS_POM_VERSION/xml/features|" \ + $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg + + # Patch the Apache Karaf distribution file to load default ONOS boot features + export BOOT_FEATURES="webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui" + perl -pi.old -e "s|^(featuresBoot=.*)|\1,$BOOT_FEATURES|" \ + $ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg + + # Patch the Apache Karaf distribution with ONOS branding bundle + cp $M2_REPO/org/onosproject/onos-branding/$ONOS_POM_VERSION/onos-branding-*.jar \ + $ONOS_STAGE/$KARAF_DIST/lib + + # Patch in the ONOS version file + echo $ONOS_VERSION > $ONOS_STAGE/VERSION +} + +function build_compressed_package() { + # Package up the ONOS tar file + cd $ONOS_STAGE_ROOT + rm -f $ONOS_TAR $ONOS_ZIP + COPYFILE_DISABLE=1 tar zcf $ONOS_TAR $ONOS_BITS + + # Figure out whether we should build ONOS zip file and if so, build it. + which zip >/dev/null && [ -z "$ONOS_TAR_ONLY" ] && buildZip=true || unset buildZip + [ -n "$buildZip" ] && zip -rq $ONOS_ZIP $ONOS_BITS + + # Report on the archives that were built and clean-up + [ -n "$buildZip" ] && ls -lh $ONOS_TAR $ONOS_ZIP || ls -lh $ONOS_TAR + rm -r $ONOS_STAGE +} + +# Build a DEB package +function build_deb() { + echo "You need to be root in order to generate a proper DEB package." + + sudo rm -fr $ONOS_DEB_ROOT + + mkdir -p $ONOS_DEB_ROOT/{DEBIAN,opt,etc/init} + + { + echo "Package: ONOS" + echo "Architecture: all" + echo "Maintainer: ONOS Project" + echo "Depends: debconf (>= 0.5.00), default-jre-headless (>= 1.8) | openjdk-8-jre | oracle-java8-installer" + echo "Priority: optional" + echo "Version: $ONOS_POM_VERSION" + echo "Description: Open Network Operating System (ONOS) is an" + echo " opensource SDN controller." + } > $ONOS_DEB_ROOT/DEBIAN/control + + cp -r $ONOS_STAGE $ONOS_DEB_ROOT/opt/onos + cp $ONOS_ROOT/tools/package/debian/onos.conf $ONOS_DEB_ROOT/etc/init/ + + mkdir -p $ONOS_DEB_ROOT/opt/onos/var/ + + sudo chown -R root:root $ONOS_DEB_ROOT + + sudo dpkg-deb --build $ONOS_DEB_ROOT > /dev/null && + sudo mv $ONOS_STAGE_ROOT/deb.deb $ONOS_DEB && ls -l $ONOS_DEB +} + +# Build an RPM package +function build_rpm() { + read -r -p "WARN: rpm-build utility and root priviledges are need to build the package. Do you want to continue? [Y/n] " response + case $response in + [nN][oO]) + exit 0 + ;; + *) + sudo rm -fr $ONOS_RPM_ROOT + + sudo yum -y install rpm-build + + mkdir -p $ONOS_RPM_ROOT/{BUILD,RPMS,SOURCES/ONOS-$ONOS_RPM_VERSION/{etc/init,opt},SPECS,SRPMS} + + cp -r $ONOS_STAGE $ONOS_RPM_ROOT/SOURCES/ONOS-$ONOS_RPM_VERSION/opt/onos + cp $ONOS_ROOT/tools/package/debian/onos.conf $ONOS_RPM_ROOT/SOURCES/ONOS-$ONOS_RPM_VERSION/etc/init/ + + cd $ONOS_RPM_ROOT/SOURCES + COPYFILE_DISABLE=1 tar zcf ONOS-$ONOS_RPM_VERSION.tar.gz ONOS-$ONOS_RPM_VERSION + + { + echo "Name: ONOS" + echo "Version: $ONOS_RPM_VERSION" + echo "Release: 1" + echo "Summary: Open Networking Operating System (ONOS)" + echo "Vendor: ONOS Project" + echo "Packager: ONOS Project" + echo "Group: Applications/Engineering" + echo "Requires: jre >= 1:8" + echo "License: Apache 2.0" + echo "URL: http://www.onosproject.org" + echo "Source0: ONOS-$ONOS_RPM_VERSION.tar.gz" + echo "BuildArch: noarch" + echo "BuildRoot: %{_tmppath}/%{name}-buildroot" + echo "%description" + echo "Open Network Operating System (ONOS) is an opensource SDN controller." + echo -e "\n" + echo "%prep" + echo "%setup -q" + echo -e "\n" + echo "%install" + echo "mkdir -p %{buildroot}" + echo "cp -R * %{buildroot}" + echo -e "\n" + echo "%clean" + echo "rm -rf %{buildroot}" + echo -e "\n" + echo "%files" + echo "%defattr(-,root,root,-)" + echo "/etc/init/onos.conf" + echo "/opt/onos/" + echo -e "\n" + echo "%post" + echo "echo ONOS successfully installed at /opt/onos" + } > $ONOS_RPM_ROOT/SPECS/onos.spec + + rpmbuild --define "_topdir $ONOS_RPM_ROOT" -bb $ONOS_RPM_ROOT/SPECS/onos.spec + + cp $ONOS_RPM_ROOT/RPMS/noarch/ONOS-$ONOS_RPM_VERSION-1.noarch.rpm $ONOS_STAGE_ROOT && ls -l $ONOS_STAGE_ROOT/ONOS-$ONOS_RPM_VERSION-1.noarch.rpm + ;; + esac +} + +# Script entry point +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +# Bail on any errors +set -e + +# Before starting make sure the environment is clan - delete onos staging folder +rm -fr $ONOS_STAGE + +# If there are parameters check if we want to build a deb - otherwise build tar.gz +case ${1:---tar} in + "--tar" | "-T") build_stage_dir + build_compressed_package + ;; + "--deb" | "-D") build_stage_dir + build_deb + ;; + "--rpm" | "-R") build_stage_dir + build_rpm + ;; + *) echo "usage: $(basename $0) [--tar|--deb|--rpm]" >&2 && exit 1 + ;; +esac diff --git a/framework/src/onos/tools/build/onos-package-test b/framework/src/onos/tools/build/onos-package-test new file mode 100755 index 00000000..6328bb81 --- /dev/null +++ b/framework/src/onos/tools/build/onos-package-test @@ -0,0 +1,31 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Packages ONOS test facilities into onos-test.tar.gz +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +# Bail on any errors +set -e + +rm -fr $ONOS_TEST_STAGE # Remove this when package script is completed + +# Create the stage directory and warp into it +mkdir -p $ONOS_TEST_STAGE/tools/test \ + $ONOS_TEST_STAGE/tools/dev \ + $ONOS_TEST_STAGE/tools/build \ + $ONOS_TEST_STAGE/tools/package/config + +cp -r $ONOS_ROOT/tools/test $ONOS_TEST_STAGE/tools +cp $ONOS_ROOT/tools/dev/bash_profile $ONOS_TEST_STAGE/tools/dev +cp $ONOS_ROOT/tools/build/envDefaults $ONOS_TEST_STAGE/tools/build + +cd $ONOS_TEST_STAGE_ROOT + +# Now package up the ONOS test tools tar file +COPYFILE_DISABLE=1 tar zcf $ONOS_TEST_TAR $ONOS_TEST_BITS +cd $ONOS_TEST_STAGE_ROOT +# rm -r $ONOS_TEST_STAGE diff --git a/framework/src/onos/tools/build/onos-release b/framework/src/onos/tools/build/onos-release new file mode 100755 index 00000000..8e7f7fb0 --- /dev/null +++ b/framework/src/onos/tools/build/onos-release @@ -0,0 +1,41 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Drives the ONOS release process. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +set -e + +export NEW_VERSION=$1 +[ -z "$NEW_VERSION" ] && echo "New ONOS version not specified" && exit 1 + +export NEW_VERSION_SHORT=${NEW_VERSION%-SNAPSHOT} +[ "$NEW_VERSION" != "$NEW_VERSION_SHORT" ] && echo "Version is a SNAPSHOT" && exit 1; + +cd $ONOS_ROOT + +# TODO: Create a new branch for this activity? + +# Change the version +onos-change-version $NEW_VERSION +export ONOS_VERSION=$NEW_VERSION + +# Build ONOS & deploy to staging repo using the release profile. +onos-build && onos-package && mvn -Prelease clean deploy -DskipTests + +# Build ONOS docs +onos-build-docs + +# Build ONOS archetypes & deploy to staging repo using the release profile. +# Note that release of the staging repository is a separate manual step. +pushd tools/package/archetypes/ +mvn clean install && onos-archetypes-test && mvn -Prelease clean deploy +popd + +# Commit newly versioned artifacts and issue a tag. +git commit -a -m"Tagging $NEW_VERSION" +git tag -sm"Tagging $NEW_VERSION" $NEW_VERSION #signed tag + +# TODO: push? diff --git a/framework/src/onos/tools/build/onos-snapshot b/framework/src/onos/tools/build/onos-snapshot new file mode 100755 index 00000000..e482df92 --- /dev/null +++ b/framework/src/onos/tools/build/onos-snapshot @@ -0,0 +1,27 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Drives the ONOS snapshot process. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +export NEW_VERSION=$1 +[ -z "$NEW_VERSION" ] && echo "New ONOS version not specified" && exit 1 + +export NEW_VERSION_SHORT=${NEW_VERSION%-SNAPSHOT} +[ "$NEW_VERSION" = "$NEW_VERSION_SHORT" ] && echo "Version is not a SNAPSHOT" && exit 1; + +cd $ONOS_ROOT + +# TODO: Create a new branch for this activity? + +# Change the version +onos-change-version $NEW_VERSION + +# Commit newly versioned artifacts. +git commit -a -m"Starting snapshot $NEW_VERSION" + +# TODO: push? diff --git a/framework/src/onos/tools/build/onos-test b/framework/src/onos/tools/build/onos-test new file mode 100755 index 00000000..c6819613 --- /dev/null +++ b/framework/src/onos/tools/build/onos-test @@ -0,0 +1,22 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Launches the ONOS tests on the current cell environment. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + +onos-package +onos-verify-cell || exit 1 + +for node in $nodes; do onos-install -f $node 1>/dev/null & done + +# Wait for shutdown before waiting for restart +sleep 3 + +for node in $nodes; do onos-wait-for-start $node; done +for node in $nodes; do onos-check-logs $node; done diff --git a/framework/src/onos/tools/build/onos-upload-bits b/framework/src/onos/tools/build/onos-upload-bits new file mode 100755 index 00000000..e3bb83cd --- /dev/null +++ b/framework/src/onos/tools/build/onos-upload-bits @@ -0,0 +1,14 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Uploads ONOS distributable bits. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +#FIXME need to export s3Creds +#TODO we could verify that ONOS_VERSION is set, and only upload that version + +onosUploadBits.py diff --git a/framework/src/onos/tools/build/onos-upload-docs b/framework/src/onos/tools/build/onos-upload-docs new file mode 100755 index 00000000..f74a13ff --- /dev/null +++ b/framework/src/onos/tools/build/onos-upload-docs @@ -0,0 +1,23 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Uploads ONOS Java API docs. +# ----------------------------------------------------------------------------- + +set -e + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +user=${1:-jenkins} +remote=$user@wiki.onosproject.org + +scp $ONOS_ROOT/docs/target/onos-apidocs-$ONOS_VERSION.tar.gz $remote:/tmp +ssh $remote " + mkdir -p /var/www/api/$ONOS_VERSION + cd /var/www/api/$ONOS_VERSION + tar zxf /tmp/onos-apidocs-$ONOS_VERSION.tar.gz + mv onos-apidocs-$ONOS_VERSION/* . + rm -rf onos-apidocs-$ONOS_VERSION + + # TODO: optionally bump /var/www/api/index.html +" diff --git a/framework/src/onos/tools/build/onosUploadBits.py b/framework/src/onos/tools/build/onosUploadBits.py new file mode 100755 index 00000000..b86f45d0 --- /dev/null +++ b/framework/src/onos/tools/build/onosUploadBits.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# ----------------------------------------------------------------------------- +# Uploads ONOS distributable bits. +# ----------------------------------------------------------------------------- + +#FIXME need to export s3Creds + +import re +from os import listdir +from os.path import isfile, join + +from uploadToS3 import uploadFile + +nightlyTag = 'NIGHTLY' +bitsPath = '/tmp' + +prefix = 'onos-(\d+\.\d+\.\d+)' +buildNum = '\.?([\w-]*)' +ext = '\.(?:tar\.gz|zip)' + +def findBits( path ): + for file in listdir( path ): + filePath = join( path, file ) + if not isfile( filePath ): + continue + + regex = prefix + buildNum + ext + match = re.match( regex, file ) + if match: + version = match.group(1) + build = match.group(2) + if build: + if 'NIGHTLY' in build or 'rc' in build: + uploadFile(filePath, dest='nightly/') + else: + #no build; this is a release + uploadFile(filePath, dest='release/') + +if __name__ == '__main__': + findBits( '/tmp' ) diff --git a/framework/src/onos/tools/build/pom.xml b/framework/src/onos/tools/build/pom.xml new file mode 100644 index 00000000..ea473ed2 --- /dev/null +++ b/framework/src/onos/tools/build/pom.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <prerequisites> + <maven>3.0.0</maven> + </prerequisites> + + <groupId>org.onosproject</groupId> + <artifactId>onos-base</artifactId> + <packaging>pom</packaging> + <version>1</version> + + <name>${project.artifactId}</name> + <description>Open Network Operating System Base Pom</description> + + <url>http://onosproject.org/</url> + + <scm> + <connection>scm:git:https://gerrit.onosproject.org/onos</connection> + <developerConnection>scm:git:https://gerrit.onosproject.org/onos</developerConnection> + <url>http://gerrit.onosproject.org/</url> + </scm> + + <licenses> + <license> + <name>Apache License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + </licenses> + + <developers> + <developer> + <organization>Open Networking Lab</organization> + <url>http://onlab.us</url> + </developer> + </developers> + + <distributionManagement> + <snapshotRepository> + <id>ossrh</id> + <url>https://oss.sonatype.org/content/repositories/snapshots</url> + </snapshotRepository> + </distributionManagement> + + <profiles> + <profile> + <id>release</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>2.2.1</version> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar-no-fork</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.9.1</version> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-gpg-plugin</artifactId> + <version>1.5</version> + <executions> + <execution> + <id>sign-artifacts</id> + <phase>verify</phase> + <goals> + <goal>sign</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.5</version> + <extensions>true</extensions> + <configuration> + <serverId>ossrh</serverId> + <nexusUrl>https://oss.sonatype.org/</nexusUrl> + <autoReleaseAfterClose>false</autoReleaseAfterClose> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/framework/src/onos/tools/build/uploadToS3.py b/framework/src/onos/tools/build/uploadToS3.py new file mode 100755 index 00000000..a16235cd --- /dev/null +++ b/framework/src/onos/tools/build/uploadToS3.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +""" +Upload a file to S3 +""" + +from sys import argv, stdout +from time import time +from os.path import basename +from optparse import OptionParser + +from boto.s3.key import Key +from boto.s3.connection import S3Connection + + +def uploadFile( filename, dest=None, bucket=None, overwrite=False ): + "Upload a file to a bucket" + if not bucket: + bucket = 'onos' + if not dest: + key = basename( filename ) + else: + key = dest + basename( filename ) #FIXME add the / + print '* Uploading', filename, 'to bucket', bucket, 'as', key + stdout.flush() + start = time() + def callback( transmitted, size ): + "Progress callback for set_contents_from_filename" + elapsed = time() - start + percent = 100.0 * transmitted / size + kbps = .001 * transmitted / elapsed + print ( '\r%d bytes transmitted of %d (%.2f%%),' + ' %.2f KB/sec ' % + ( transmitted, size, percent, kbps ) ), + stdout.flush() + conn = S3Connection() + bucket = conn.get_bucket( bucket ) + k = Key( bucket ) + k.key = key + if overwrite or not k.exists(): + k.set_contents_from_filename( filename, cb=callback, num_cb=100 ) + print + elapsed = time() - start + print "* elapsed time: %.2f seconds" % elapsed + else: + print 'file', basename( filename ), 'already exists in', bucket.name + +if __name__ == '__main__': + usage = "Usage: %prog [options] <file to upload>" + parser = OptionParser(usage=usage) + parser.add_option("-b", "--bucket", dest="bucket", + help="Bucket on S3") + parser.add_option("-d", "--dest", dest="dest", + help="Destination path in bucket") + parser.add_option("-k", "--key", dest="awsKey", + help="Bucket on S3") + parser.add_option("-s", "--secret", dest="awsSecret", + help="Bucket on S3") + parser.add_option("-f", "--force", dest="overwrite", + help="Overwrite existing file") + (options, args) = parser.parse_args() + + if len( args ) == 0: + parser.error("missing filenames") + for file in args: + uploadFile( file, options.dest, options.bucket, options.overwrite ) + + #FIXME key and secret are unused diff --git a/framework/src/onos/tools/dev/bash_profile b/framework/src/onos/tools/dev/bash_profile new file mode 100644 index 00000000..5e161ccd --- /dev/null +++ b/framework/src/onos/tools/dev/bash_profile @@ -0,0 +1,189 @@ +#!/bin/bash +# ONOS developer BASH profile conveniences +# Simply include in your own .bash_aliases or .bash_profile + +# Root of the ONOS source tree +export ONOS_ROOT=${ONOS_ROOT:-~/onos} + +# Setup some environmental context for developers +if [ -z "${JAVA_HOME}" ]; then + if [ -x /usr/libexec/java_home ]; then + export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) + elif [ -d /usr/lib/jvm/java-8-oracle ]; then + export JAVA_HOME="/usr/lib/jvm/java-8-oracle" + elif [ -d /usr/lib/jvm/java-8-openjdk-amd64 ]; then + export JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" + fi +fi + +export MAVEN=${MAVEN:-~/Applications/apache-maven-3.3.1} + +export KARAF_VERSION=${KARAF_VERSION:-3.0.3} +export KARAF_ROOT=${KARAF_ROOT:-~/Applications/apache-karaf-$KARAF_VERSION} +export KARAF_LOG=$KARAF_ROOT/data/log/karaf.log + +# Setup a path +export PATH="$PATH:$ONOS_ROOT/tools/dev/bin" +export PATH="$PATH:$ONOS_ROOT/tools/test/bin:$ONOS_ROOT/tools/test/scenarios/bin" +export PATH="$PATH:$ONOS_ROOT/tools/build" +export PATH="$PATH:$MAVEN/bin:$KARAF_ROOT/bin" + +# Setup cell enviroment +export ONOS_CELL=${ONOS_CELL:-local} + +# Setup default web user/password +export ONOS_WEB_USER=onos +export ONOS_WEB_PASS=rocks + +# Setup default location of test scenarios +export ONOS_SCENARIOS=$ONOS_ROOT/tools/test/scenarios + +# Convenience utility to warp to various ONOS source projects +# e.g. 'o api', 'o dev', 'o' +function o { + cd $(find $ONOS_ROOT/ -type d | egrep -v '\.git|target|gen-src' | \ + egrep "${1:-$ONOS_ROOT}" | egrep -v "$ONOS_ROOT/.+/src/" | head -n 1) +} + +# Short-hand for 'mvn clean install' for us lazy folk +alias mci='mvn clean install' +alias mcis='mvn clean install -DskipTests -Dcheckstyle.skip -U -T 1C' +alias mis='mvn install -DskipTests -Dcheckstyle.skip -U -T 1C' + +# Short-hand for ONOS build, package and test. +alias ob='onos-build' +alias obi='onos-build -Dmaven.test.failure.ignore=true' +alias obs='onos-build-selective' +alias obd='onos-build-docs' +alias op='onos-package' +alias ok='onos-karaf' +alias ot='onos-test' +alias ol='onos-log' +alias ow='onos-watch' +alias ocl='onos-check-logs' +alias oi='setPrimaryInstance' +alias pub='onos-push-update-bundle' + +# Short-hand for tailing and searching the ONOS (karaf) log +alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log' +alias ll='less $KARAF_LOG' +alias gl='grep $KARAF_LOG --colour=auto -E -e ' + +function filterLocalLog { + tl | grep --colour=always -E -e "${1-org.onlab|org.onosproject}" +} +alias tlo='filterLocalLog' +alias tle='tlo "ERROR|WARN|Exception|Error"' + +function filterLog { + ol | grep --colour=always -E -e "${1-org.onlab|org.onosproject}" +} +alias olo='filterLog' +alias ole='olo "ERROR|WARN|Exception|Error"' + +# Pretty-print JSON output +alias pp='python -m json.tool' + +# Short-hand to launch Java API docs, REST API docs and ONOS GUI +alias docs='open $ONOS_ROOT/docs/target/site/apidocs/index.html' +alias rsdocs='onos-rsdocs' +alias gui='onos-gui' + + +# Test related conveniences + +# SSH to a specified ONOS instance +alias sshctl='onos-ssh' +alias sshnet='onos-ssh $OCN' + + +# Sets the primary instance to the specified instance number. +function setPrimaryInstance { + export OCI=$(env | egrep "OC[0-9]+" | sort | egrep OC${1:-1} | cut -d= -f2) + echo $OCI +} + +# Applies the settings in the specified cell file or lists current cell definition +# if no cell file is given. +function cell { + if [ -n "$1" ]; then + [ ! -f $ONOS_ROOT/tools/test/cells/$1 ] && \ + echo "No such cell: $1" >&2 && return 1 + unset ONOS_CELL ONOS_NIC ONOS_IP ONOS_APPS ONOS_BOOT_FEATURES + unset OCI OCN OCT ONOS_INSTANCES ONOS_USER ONOS_GROUP ONOS_FEATURES + unset $(env | sed -n 's:\(^OC[0-9]\{1,\}\)=.*:\1 :g p') + export ONOS_WEB_USER=onos + export ONOS_WEB_PASS=rocks + export ONOS_CELL=$1 + . $ONOS_ROOT/tools/test/cells/$1 + export ONOS_INSTANCES=$(env | grep 'OC[0-9]*=' | sort | cut -d= -f2) + setPrimaryInstance 1 >/dev/null + cell + else + env | egrep "ONOS_CELL" + env | egrep "OCI" + env | egrep "OC[0-9]+" | sort + env | egrep "OC[NT]" + env | egrep "ONOS_" | egrep -v 'ONOS_ROOT|ONOS_CELL|ONOS_INSTANCES' | sort + fi +} + +cell $ONOS_CELL > /dev/null + +# Lists available cells +function cells { + for cell in $(ls -1 $ONOS_ROOT/tools/test/cells); do + printf "%-16s %s\n" \ + "$([ $cell = $ONOS_CELL ] && echo $cell '*' || echo $cell)" \ + "$(grep '^#' $ONOS_ROOT/tools/test/cells/$cell | head -n 1)" + done +} + +# Miscellaneous +function spy { + ps -ef | egrep "$@" | grep -v egrep +} + +function nuke { + spy "$@" | cut -c7-11 | xargs kill +} + +# Edit a cell file by providing a cell name. Opens the cell file in $EDITOR. +function vicell() { + local apply=false + local create=false + local cdf="" + local cpath="${ONOS_ROOT}/tools/test/cells/" + + if [ -z "$1" ] || [ "$1" = "-h" ] ; then + printf "usage: vicell [file] [options]\n\noptions:\n" + printf "\t-a: apply the cell after editing\n" + printf "\t-e: [editor] set EDITOR to [editor] (default *vi*)\n" + printf "\t-c: create cell file if none exist\n\n" + return 1 + fi + + while [ $# -gt 0 ]; do + case "$1" in + -a) apply=true ;; + -e) EDITOR=$2; shift ;; + -c) create=true ;; + *) cdf="$1" ;; + esac + shift + done + + if [ ! -e "${cpath}${cdf}" ] && [ "$create" = "false" ]; then + printf "${cdf} : no such cell\n" && return 1 + fi + + if [ -z "${EDITOR}" ] || [ -x "$(which ${EDITOR})" ]; then + unset EDITOR && vi ${cpath}${cdf} + else + $EDITOR ${cpath}${cdf} + fi + ($apply) && cell ${cdf} +} + +# autocomplete for certain utilities +. ${ONOS_ROOT}/tools/test/bin/ogroup-opts diff --git a/framework/src/onos/tools/dev/bin/clean-branches.py b/framework/src/onos/tools/dev/bin/clean-branches.py new file mode 100755 index 00000000..3de7cb70 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/clean-branches.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +from subprocess import check_output +import sys + +def get_merged_branches_by_change_id(): + '''a list of merged branches, by change id excluding support branches and master''' + raw_changeIds = check_output('git log origin/master | grep -i change-id | awk {\' print $2 \'}', shell=True) + changeIds = [b.strip() for b in raw_changeIds.split('\n') if b.strip()] + raw_branches = check_output('git branch -a', shell=True) + branches = [b.strip() for b in raw_branches.split('\n') + if b.strip() and not b.startswith('*') and \ + not b.strip().startswith('onos') and not b.strip().startswith('remotes') and b.strip() != 'master'] + to_delete = [] + for branch in branches: + raw_local_change_ids = check_output('git show %s | grep -i change-id | awk {\' print $2 \'}' % branch, shell=True) + local_change_ids = [ b.strip() for b in raw_local_change_ids.split('\n') if b.strip() ] + for local_change_id in local_change_ids: + if local_change_id in changeIds and branch not in to_delete: + to_delete.append(branch) + + return to_delete + + +def delete_branch(branch): + return check_output('git branch -D %s' % branch, shell=True).strip() + + +if __name__ == '__main__': + dry_run = '--confirm' not in sys.argv + one_by_one = '--one-by-one' in sys.argv + to_delete = get_merged_branches_by_change_id() + if len(to_delete) == 0: + print "Nothing to clean" + sys.exit(0) + for branch in to_delete: + if dry_run: + print branch + else: + if one_by_one: + print 'Do you want to delete branch %s [y/N]' % branch + ans = raw_input() + if ans == 'y' or ans == 'Y': + print delete_branch(branch) + else: + print delete_branch(branch) + + if dry_run: + print '*****************************************************************' + print 'Did not actually delete anything yet, pass in --confirm to delete' + print diff --git a/framework/src/onos/tools/dev/bin/onos-app b/framework/src/onos/tools/dev/bin/onos-app new file mode 100755 index 00000000..d6fe562b --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-app @@ -0,0 +1,72 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Tool to manage ONOS applications using REST API. +# ----------------------------------------------------------------------------- + +node=${1:-$OCI} +cmd=${2:-list} +app=${3} + +export URL=http://$node:8181/onos/v1/applications +export HDR="-HContent-Type:application/octet-stream" +export curl="curl -sS --user $ONOS_WEB_USER:$ONOS_WEB_PASS" + +# Prints usage help +function usage { + echo "usage: onos-app <node-ip> list" >&2 + echo " onos-app <node-ip> {install|install!} <app-file>" >&2 + echo " onos-app <node-ip> {reinstall|reinstall!} [<app-name>] <app-file>" >&2 + echo " onos-app <node-ip> {activate|deactivate|uninstall} <app-name>" >&2 + exit 1 +} + +# Extract app name from the specified *.oar file +function appName { + aux=/tmp/aux$$.jar + cp $1 $aux + pushd /tmp >/dev/null + jar xf $aux app.xml && grep name= app.xml | cut -d\" -f2 + rm -f $aux /tmp/app.xml + popd >/dev/null +} + +[ -z $node -o "$node" = "-h" -o "$node" = "--help" -o "$node" = "-?" ] && usage + +case $cmd in + list) $curl -X GET $URL;; + install!|install) + [ $cmd = "install!" ] && activate="?activate=true" + [ $# -lt 3 -o ! -f $app ] && usage + $curl -X POST $HDR $URL$activate --data-binary @$app + ;; + + reinstall!|reinstall) + [ $cmd = "reinstall!" ] && activate="?activate=true" + [ $# -lt 4 -a ! -f "$3" ] && usage + [ $# -eq 4 -a ! -f "$4" ] && usage + oar=$4 + [ $# -lt 4 ] && oar=$3 && app=$(appName $oar) + $curl -X DELETE $URL/$app + $curl -X POST $HDR $URL$activate --data-binary @$oar + ;; + + uninstall) + [ $# -lt 3 ] && usage + $curl -X DELETE $URL/$app + ;; + activate) + [ $# -lt 3 ] && usage + $curl -X POST $URL/$app/active + ;; + deactivate) + [ $# -lt 3 ] && usage + $curl -X DELETE $URL/$app/active + ;; + + *) usage;; +esac + + +status=$? +echo # new line for prompt +exit $status diff --git a/framework/src/onos/tools/dev/bin/onos-build-selective b/framework/src/onos/tools/dev/bin/onos-build-selective new file mode 100755 index 00000000..ac2dec8e --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-build-selective @@ -0,0 +1,44 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Selectively builds only those projects that contained modified Java files. +# ---------------------------------------------------------------------------- + +cd $ONOS_ROOT + +projects=$(find $ONOS_ROOT -type f -path '*/src/*' \ + -exec $ONOS_ROOT/tools/dev/bin/onos-build-selective-hook {} \; | \ + grep -v -f $ONOS_ROOT/tools/dev/bin/onos-build-selective.exclude | \ + sort -u | sed "s:$ONOS_ROOT::g" | tr '\n' ',' | \ + sed 's:/,:,:g;s:,/:,:g;s:^/::g;s:,$::g') + +if [ -n "$projects" ]; then + # Ascertain artifact IDs of the projects to be rebuilt + modulesERE="" + for pd in ${projects//,/ }; do + artifactId=$(grep -E "^ <artifactId>.*</artifactId>$" ${pd}/pom.xml | \ + sed 's/.[^>]*>//;s/<.*//') + modulesERE="$modulesERE|$artifactId" + done + modulesERE=${modulesERE#|*} + + # Search through staged app.xml files for any apps that require one or + # more of the modified artifacts. + appProjects=$(find $ONOS_ROOT -type f -path '*/target/oar/app.xml' | \ + xargs grep '<artifact>' | grep -E "/($modulesERE)/" | \ + cut -d: -f1 | sed 's:/target/oar/.*::g' | \ + sort -u | sed "s:$ONOS_ROOT::g" | tr '\n' ',' | \ + sed 's:/,:,:g;s:,/:,:g;s:^/::g;s:,$::g') + + # If we found any, append those app projects to the list of projects to + # be built. + [ -n "$appProjects" ] && projects=$projects,$appProjects + + echo Building projects $projects + cd $ONOS_ROOT && mvn --projects $projects ${@:-clean install} + status=$? + + [ -n "$appProjects" ] && echo "App staging required for projects $appProjects" + exit $status +else + exit 0 +fi diff --git a/framework/src/onos/tools/dev/bin/onos-build-selective-hook b/framework/src/onos/tools/dev/bin/onos-build-selective-hook new file mode 100755 index 00000000..fbe77522 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-build-selective-hook @@ -0,0 +1,10 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Echoes project-level directory if a source file within is newer than the +# target directory. +# ---------------------------------------------------------------------------- + +[ ${1/*\//} = "package-info.java" ] && exit 0 + +project=${1/src*/} +[ ${project}target -nt $1 ] || echo ${project} diff --git a/framework/src/onos/tools/dev/bin/onos-build-selective.exclude b/framework/src/onos/tools/dev/bin/onos-build-selective.exclude new file mode 100644 index 00000000..1265494e --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-build-selective.exclude @@ -0,0 +1,9 @@ +.*/archetypes/.* +.*/maven-plugin/.* +.*/build/conf/.* +.*/docs/.* +.*/openflow/drivers/.* +.*/cord-gui/.* +.*/jdvue/.* +.*/ovsdb/api/.* +.*/netconf/flow/.*
\ No newline at end of file diff --git a/framework/src/onos/tools/dev/bin/onos-create-app b/framework/src/onos/tools/dev/bin/onos-create-app new file mode 100755 index 00000000..65b00b65 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-create-app @@ -0,0 +1,42 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Tool to create an application from scratch using ONOS Maven archetypes. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +type=${1:-bundle} + +[ $type = app ] && archetype=bundle || archetype=$type + +if [ "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ]; then + echo "usage: $(basename $0) {app|bundle|ui|cli|api} groupId artifactId version package mvn-options" + echo " All arguments are optional" + exit 1 +fi + +otherOptions="" +[ -n "$1" ] && shift +[ -n "$1" ] && otherOptions="$otherOptions -DgroupId=$1" && shift +[ -n "$1" ] && otherOptions="$otherOptions -DartifactId=$1" && dir=$1 && shift +[ -n "$1" ] && otherOptions="$otherOptions -Dversion=$1" && shift +[ -n "$1" ] && otherOptions="$otherOptions -Dpackage=$1" && shift + +mvn archetype:generate -DarchetypeGroupId=org.onosproject \ + -DarchetypeArtifactId=onos-$archetype-archetype \ + -DarchetypeVersion=$ONOS_POM_VERSION $otherOptions "$@" + +# Patch the pom.xml file to make this an app. +if [ $type = app ]; then + # We need to add a few lines to the pom.xml to make this an app + if [ -n "$dir" ] && [ -d $dir ]; then + egrep -v " (<!--|-->)" $dir/pom.xml > $dir/pom.app.xml + mv $dir/pom.app.xml $dir/pom.xml + else + echo + echo "IMPORTANT:" + echo "To build the application, you need to uncomment the 'onos.app.name' and 'onos.app.origin' properties in the pom.xml" + echo + fi +fi diff --git a/framework/src/onos/tools/dev/bin/onos-karaf b/framework/src/onos/tools/dev/bin/onos-karaf new file mode 100755 index 00000000..9c575fb4 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-karaf @@ -0,0 +1,7 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Makes sure local ONOS karaf instance is primed & staged and then launches +# karaf using the supplied arguments. +# ----------------------------------------------------------------------------- + +onos-setup-karaf && karaf "$@"
\ No newline at end of file diff --git a/framework/src/onos/tools/dev/bin/onos-local-log b/framework/src/onos/tools/dev/bin/onos-local-log new file mode 100755 index 00000000..a17d3b9c --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-local-log @@ -0,0 +1,10 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# Continuously watches the Apache Karaf log; survives 'karaf clean' +# ---------------------------------------------------------------------------- +KARAF_LOG=${KARAF_LOG:-~/apache-karaf-$KARAF_VERSION/data/log/karaf.log} + +while true; do + [ ! -f $KARAF_LOG ] && sleep 2 && continue + tail -n 512 -f -F $KARAF_LOG +done diff --git a/framework/src/onos/tools/dev/bin/onos-setup-karaf b/framework/src/onos/tools/dev/bin/onos-setup-karaf new file mode 100755 index 00000000..3323d9d1 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-setup-karaf @@ -0,0 +1,123 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Downloads and sets-up Apache Karaf as a basis for running ONOS locally +# as a single-instance. +# +# Note that this in no way impacts the method for running ONOS remotely. +# For that, one should use onos-package and onos-install tools. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +# TODO: consider putting this under ~/Applications/onos/apache-karaf-... +export KARAF_ROOT=${KARAF_ROOT:-~/Applications/apache-karaf-$KARAF_VERSION} +export STAGE=$(dirname $KARAF_ROOT) + +# Validates the specified IP regular expression against existing adapters. +# Excludes local-loopback. +function validateIp { + ifconfig | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep $1 +} + +# Clean the previous Karaf directory if requested and if it exists. +if [ "$1" = "clean" ]; then + shift + CLEAN="true" + [ -d $KARAF_ROOT ] && rm -fr $KARAF_ROOT $STAGE/apps $STAGE/config +fi + +ONOS_IP=${ONOS_IP:-127.0.0.1} +IP="${1:-$ONOS_IP}" + +# If IP was not given, nor configured attempt to use ONOS_NIC env. variable +if [ -z "$IP" -a -n "$ONOS_NIC" ]; then + IP=$(validateIp $ONOS_NIC) + [ -z "$IP" ] && echo "No adapter with IP matching $ONOS_NIC found!" +else + # Otherwise, verify that the IP address given exists among the adapters. + saveIp=$IP + IP=$(validateIp $IP) + [ -z "$IP" ] && echo "No adapter with IP $saveIp found!" +fi + +# If IP is still not surmised or if usage was requested, show usage and IPs. +if [ -z "$IP" -o "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ]; then + echo "usage: $(basename $0) [clean] <ip-address>" + echo "Available IP addresses are:" + validateIp . + exit 1 +fi + +SUBNET="$(echo $IP | cut -d. -f1-3)" + +# Bail on any errors +set -e + +# Check if Apache Karaf is already installed. +if [ ! -d $KARAF_ROOT ]; then + # Check if Apache Karaf bits are available and if not, fetch them. + if [ ! -f $KARAF_TAR ]; then + echo "Downloading $KARAF_TAR..." + curl -sL http://downloads.onosproject.org/third-party/apache-karaf-$KARAF_VERSION.tar.gz > $KARAF_TAR + fi + [ ! -f $KARAF_ZIP -a ! -f $KARAF_TAR ] && \ + echo "Apache Karaf bits $KARAF_ZIP or $KARAF_TAR not found" && exit 1 + + echo "Unpacking $KARAF_TAR to $STAGE..." + mkdir -p $STAGE + cd $STAGE + tar zxf $KARAF_TAR + rm -rf $KARAF_ROOT/demos +fi + +if ! grep -q "/onos-features/" $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then + # Patch the Apache Karaf distribution file to add ONOS features repository + echo "Adding ONOS feature repository..." + perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onosproject/onos-features/$ONOS_POM_VERSION/xml/features|" \ + $KARAF_ROOT/etc/org.apache.karaf.features.cfg +fi + +if ! grep -q ",onos-api," $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then + # Patch the Apache Karaf distribution file to load default ONOS boot features + export BOOT_FEATURES="webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui" + echo "Adding ONOS boot features $BOOT_FEATURES..." + perl -pi.old -e "s|^(featuresBoot=.*)|\1,$BOOT_FEATURES|" \ + $KARAF_ROOT/etc/org.apache.karaf.features.cfg +fi + +if [ ! -f $KARAF_ROOT/lib/onos-branding-$ONOS_POM_VERSION.jar ]; then + # Patch the Apache Karaf distribution with ONOS branding bundle + echo "Branding as ONOS..." + rm -f $KARAF_ROOT/lib/onos-branding-*.jar + cp $M2_REPO/org/onosproject/onos-branding/$ONOS_POM_VERSION/onos-branding-$ONOS_POM_VERSION.jar \ + $KARAF_ROOT/lib +fi + +echo "Creating local cluster configs for IP $IP..." +[ -d $STAGE/config ] || mkdir -p $STAGE/config +cat > $STAGE/config/cluster.json <<EOF + { "ipPrefix": "$SUBNET.*", + "nodes":[ { "id": "$IP", "ip": "$IP", "tcpPort": 9876 }]} +EOF + +cat > $STAGE/config/tablets.json <<EOF + { "nodes": [ { "ip": "$IP", "id": "$IP", "tcpPort": 9876 }], + "partitions": { "p1": [ { "ip": "$IP", "id": "$IP", "tcpPort": 9876 }]}} +EOF + +if [ "$CLEAN" = "true" ]; then + echo "Copying package configs..." + cp -r $ONOS_ROOT/tools/package/etc/* $KARAF_ROOT/etc/ + cp -r $ONOS_ROOT/tools/package/config/* $STAGE/config/ +fi + +echo "Staging builtin apps..." +rm -fr $STAGE/apps +onos-stage-apps $STAGE/apps $KARAF_ROOT/system + +ACTIVE_APPS=${ONOS_APPS:-drivers,openflow} +echo "Customizing apps to be auto-activated: $ACTIVE_APPS..." +for app in ${ACTIVE_APPS//,/ }; do + touch $STAGE/apps/org.onosproject.$app/active +done diff --git a/framework/src/onos/tools/dev/bin/onos-setup-ubuntu-devenv b/framework/src/onos/tools/dev/bin/onos-setup-ubuntu-devenv new file mode 100755 index 00000000..d528c6b2 --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-setup-ubuntu-devenv @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Script to install ONOS dependencies on Ubuntu 14.04 +# + +echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections + +echo debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections + +sudo apt-get install software-properties-common -y +sudo add-apt-repository ppa:webupd8team/java -y +sudo apt-get update && sudo apt-get install oracle-java8-installer oracle-java8-set-default git wget -y +export JAVA_HOME=/usr/lib/jvm/java-8-oracle + +cd; mkdir Downloads Applications +cd Downloads +wget http://download.nextag.com/apache/karaf/3.0.3/apache-karaf-3.0.3.tar.gz +wget http://archive.apache.org/dist/maven/maven-3/3.3.1/binaries/apache-maven-3.3.1-bin.tar.gz +tar -zxvf apache-karaf-3.0.3.tar.gz -C ../Applications/ +tar -zxvf apache-maven-3.3.1-bin.tar.gz -C ../Applications/ + diff --git a/framework/src/onos/tools/dev/bin/onos-update-bundle b/framework/src/onos/tools/dev/bin/onos-update-bundle new file mode 100755 index 00000000..9e9e08bb --- /dev/null +++ b/framework/src/onos/tools/dev/bin/onos-update-bundle @@ -0,0 +1,16 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Update bundle on locally running karaf. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +cd ~/.m2/repository +jar=$(find org/onosproject -type f -name '*.jar' | grep -e $1 | grep -v -e -tests | head -n 1) + +[ -z "$jar" ] && echo "No bundle $1 found for" && exit 1 + +bundle=$(echo $(basename $jar .jar) | sed 's/-[0-9].*//g') + +client "bundle:update -f $bundle" 2>/dev/null diff --git a/framework/src/onos/tools/dev/eclipse-cleanup.xml b/framework/src/onos/tools/dev/eclipse-cleanup.xml new file mode 100644 index 00000000..ee0f302d --- /dev/null +++ b/framework/src/onos/tools/dev/eclipse-cleanup.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<profiles version="2"> +<profile kind="CleanUpProfile" name="ONOS Clean Up" version="2"> +<setting id="cleanup.remove_redundant_type_arguments" value="true"/> +<setting id="cleanup.remove_unused_private_fields" value="true"/> +<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/> +<setting id="cleanup.never_use_blocks" value="false"/> +<setting id="cleanup.remove_unused_private_methods" value="true"/> +<setting id="cleanup.add_missing_deprecated_annotations" value="true"/> +<setting id="cleanup.convert_to_enhanced_for_loop" value="false"/> +<setting id="cleanup.remove_unnecessary_nls_tags" value="true"/> +<setting id="cleanup.sort_members" value="false"/> +<setting id="cleanup.remove_unused_local_variables" value="false"/> +<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/> +<setting id="cleanup.remove_unused_private_members" value="false"/> +<setting id="cleanup.remove_unnecessary_casts" value="true"/> +<setting id="cleanup.make_parameters_final" value="false"/> +<setting id="cleanup.use_this_for_non_static_field_access" value="false"/> +<setting id="cleanup.remove_private_constructors" value="true"/> +<setting id="cleanup.use_blocks" value="false"/> +<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/> +<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/> +<setting id="cleanup.always_use_this_for_non_static_field_access" value="false"/> +<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="true"/> +<setting id="cleanup.add_default_serial_version_id" value="true"/> +<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/> +<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="true"/> +<setting id="cleanup.make_variable_declarations_final" value="false"/> +<setting id="cleanup.add_missing_nls_tags" value="false"/> +<setting id="cleanup.format_source_code" value="false"/> +<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/> +<setting id="cleanup.add_missing_override_annotations" value="true"/> +<setting id="cleanup.convert_functional_interfaces" value="false"/> +<setting id="cleanup.remove_unused_private_types" value="true"/> +<setting id="cleanup.use_anonymous_class_creation" value="false"/> +<setting id="cleanup.use_type_arguments" value="false"/> +<setting id="cleanup.add_missing_methods" value="false"/> +<setting id="cleanup.make_local_variable_final" value="true"/> +<setting id="cleanup.correct_indentation" value="false"/> +<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/> +<setting id="cleanup.remove_unused_imports" value="true"/> +<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/> +<setting id="cleanup.make_private_fields_final" value="true"/> +<setting id="cleanup.add_generated_serial_version_id" value="false"/> +<setting id="cleanup.organize_imports" value="false"/> +<setting id="cleanup.remove_trailing_whitespaces" value="true"/> +<setting id="cleanup.sort_members_all" value="false"/> +<setting id="cleanup.insert_inferred_type_arguments" value="false"/> +<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/> +<setting id="cleanup.add_missing_annotations" value="true"/> +<setting id="cleanup.use_parentheses_in_expressions" value="false"/> +<setting id="cleanup.use_lambda" value="true"/> +<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/> +<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/> +<setting id="cleanup.use_this_for_non_static_method_access" value="false"/> +<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="true"/> +<setting id="cleanup.add_serial_version_id" value="false"/> +<setting id="cleanup.format_source_code_changes_only" value="false"/> +<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="true"/> +<setting id="cleanup.always_use_blocks" value="true"/> +</profile> +</profiles> diff --git a/framework/src/onos/tools/dev/eclipse-formatter.xml b/framework/src/onos/tools/dev/eclipse-formatter.xml new file mode 100644 index 00000000..4383b5ab --- /dev/null +++ b/framework/src/onos/tools/dev/eclipse-formatter.xml @@ -0,0 +1,310 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<profiles version="12"> +<profile kind="CodeFormatterProfile" name="ONOS-formatter" version="12"> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/> +<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="32"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/> +<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/> +<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="32"/> +<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/> +<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="32"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="82"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> +<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/> +<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/> +<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="32"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="32"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> +</profile> +</profiles> diff --git a/framework/src/onos/tools/dev/header.txt b/framework/src/onos/tools/dev/header.txt new file mode 100644 index 00000000..6c18c92c --- /dev/null +++ b/framework/src/onos/tools/dev/header.txt @@ -0,0 +1,13 @@ +Copyright $today.year Open Networking Laboratory + +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.
\ No newline at end of file diff --git a/framework/src/onos/tools/dev/idea-settings.jar b/framework/src/onos/tools/dev/idea-settings.jar Binary files differnew file mode 100644 index 00000000..ad1826d9 --- /dev/null +++ b/framework/src/onos/tools/dev/idea-settings.jar diff --git a/framework/src/onos/tools/dev/onos.cshrc b/framework/src/onos/tools/dev/onos.cshrc new file mode 100644 index 00000000..e5d8e628 --- /dev/null +++ b/framework/src/onos/tools/dev/onos.cshrc @@ -0,0 +1,41 @@ +#!/bin/tcsh +# ONOS developer csh/tcsh profile conveniences +# Simply include in your own $HOME/.cshrc file. E.g.: +# +# setenv ONOS_ROOT $HOME/onos +# if ( -f $ONOS_ROOT/tools/dev/onos.cshrc ) then +# source $ONOS_ROOT/tools/dev/onos.cshrc +# endif +# + +# Root of the ONOS source tree +if ( ! $?ONOS_ROOT ) then + setenv ONOS_ROOT $HOME/onos +endif + +# Setup some environmental context for developers +if ( ! $?JAVA_HOME ) then + if ( -x /usr/libexec/java_home ) then + setenv JAVA_HOME `/usr/libexec/java_home -v 1.8` + else if ( -d /usr/lib/jvm/java-8-oracle ) then + setenv JAVA_HOME /usr/lib/jvm/java-8-oracle + else if ( -d /usr/lib/jvm/java-7-openjdk-amd64 ) then + setenv JAVA_HOME /usr/lib/jvm/java-7-openjdk-amd64 + endif +endif +if ( ! $?MAVEN ) then + setenv MAVEN $HOME/Applications/apache-maven-3.3.1 +endif +if ( ! $?KARAF_VERSION ) then + setenv KARAF_VERSION 3.0.3 +endif +if ( ! $?KARAF_ROOT ) then + setenv KARAF_ROOT $HOME/Applications/apache-karaf-$KARAF_VERSION +endif +setenv KARAF_LOG $KARAF_ROOT/data/log/karaf.log + +alias onos-setup-cell ' ( env ONOS_CELL=\!^ $ONOS_ROOT/tools/test/bin/onos-show-cell \!^ ) && setenv ONOS_CELL \!^' + +set path=( $path $ONOS_ROOT/tools/dev/bin $ONOS_ROOT/tools/test/bin ) +set path=( $path $ONOS_ROOT/tools/build ) +set path=( $path $KARAF_ROOT/bin ) diff --git a/framework/src/onos/tools/package/README b/framework/src/onos/tools/package/README new file mode 100644 index 00000000..3a2e4ff0 --- /dev/null +++ b/framework/src/onos/tools/package/README @@ -0,0 +1 @@ +Artifacts for packaging onos.tar.gz. diff --git a/framework/src/onos/tools/package/archetypes/api/pom.xml b/framework/src/onos/tools/package/archetypes/api/pom.xml new file mode 100644 index 00000000..d34db1f0 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/pom.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-archetypes</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>onos-api-archetype</artifactId> + <packaging>maven-archetype</packaging> + + <description>ONOS OSGi API bundle archetype</description> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/api/src/main/resources/META-INF/maven/archetype-metadata.xml b/framework/src/onos/tools/package/archetypes/api/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 00000000..e35285e6 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<archetype-descriptor + xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" + name="onos-bundle" + xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <fileSets> + <fileSet filtered="true" packaged="true" encoding="UTF-8"> + <directory>src/main/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + </fileSets> +</archetype-descriptor> diff --git a/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/pom.xml b/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 00000000..f29a327a --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>${groupId}</groupId> + <artifactId>${artifactId}</artifactId> + <version>${version}</version> + <packaging>bundle</packaging> + + <description>ONOS OSGi API bundle archetype</description> + <url>http://onosproject.org</url> + + <properties> + <onos.version>1.3.0-SNAPSHOT</onos.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/src/main/java/AppService.java b/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/src/main/java/AppService.java new file mode 100644 index 00000000..4878f2ba --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/src/main/resources/archetype-resources/src/main/java/AppService.java @@ -0,0 +1,26 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2014 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +/** + * Skeletal ONOS application API. + */ +public interface AppService { + +} diff --git a/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/archetype.properties b/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/archetype.properties new file mode 100644 index 00000000..a1213b40 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/archetype.properties @@ -0,0 +1,21 @@ +# +# Copyright 2014 Open Networking Laboratory +# +# 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. +# + +#Thu Dec 04 09:24:50 PST 2014 +package=it.pkg +version=0.1-SNAPSHOT +groupId=archetype.it +artifactId=basic diff --git a/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/goal.txt b/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/goal.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/api/src/test/resources/projects/basic/goal.txt diff --git a/framework/src/onos/tools/package/archetypes/bundle/pom.xml b/framework/src/onos/tools/package/archetypes/bundle/pom.xml new file mode 100644 index 00000000..ff6aa52e --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/pom.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-archetypes</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>onos-bundle-archetype</artifactId> + <packaging>maven-archetype</packaging> + + <description>ONOS OSGi bundle archetype</description> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/META-INF/maven/archetype-metadata.xml b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 00000000..ef60bd05 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<archetype-descriptor + xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" + name="onos-bundle" + xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <fileSets> + <fileSet filtered="true" packaged="true" encoding="UTF-8"> + <directory>src/main/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + <fileSet filtered="true" packaged="true" encoding="UTF-8"> + <directory>src/test/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + </fileSets> +</archetype-descriptor> diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/pom.xml b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 00000000..c9e747c9 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>${groupId}</groupId> + <artifactId>${artifactId}</artifactId> + <version>${version}</version> + <packaging>bundle</packaging> + + <description>ONOS OSGi bundle archetype</description> + <url>http://onosproject.org</url> + + <properties> + <onos.version>1.3.0-SNAPSHOT</onos.version> + <!-- Uncomment to generate ONOS app from this module. + <onos.app.name>org.foo.app</onos.app.name> + <onos.app.origin>Foo, Inc.</onos.app.origin> + --> + </properties> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-osgi</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + <scope>test</scope> + <classifier>tests</classifier> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <version>1.9.8</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <version>1.20.0</version> + <executions> + <execution> + <id>generate-scr-srcdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + <configuration> + <supportedProjectTypes> + <supportedProjectType>bundle</supportedProjectType> + <supportedProjectType>war</supportedProjectType> + </supportedProjectTypes> + </configuration> + </plugin> + <plugin> + <groupId>org.onosproject</groupId> + <artifactId>onos-maven-plugin</artifactId> + <version>1.5</version> + <executions> + <execution> + <id>cfg</id> + <phase>generate-resources</phase> + <goals> + <goal>cfg</goal> + </goals> + </execution> + <execution> + <id>swagger</id> + <phase>generate-sources</phase> + <goals> + <goal>swagger</goal> + </goals> + </execution> + <execution> + <id>app</id> + <phase>package</phase> + <goals> + <goal>app</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/main/java/AppComponent.java b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/main/java/AppComponent.java new file mode 100644 index 00000000..693b6fd4 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/main/java/AppComponent.java @@ -0,0 +1,46 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2014 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Skeletal ONOS application component. + */ +@Component(immediate = true) +public class AppComponent { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Activate + protected void activate() { + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + log.info("Stopped"); + } + +} diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/test/java/AppComponentTest.java b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/test/java/AppComponentTest.java new file mode 100644 index 00000000..b981225d --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/main/resources/archetype-resources/src/test/java/AppComponentTest.java @@ -0,0 +1,49 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2014 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Set of tests of the ONOS application component. + */ +public class AppComponentTest { + + private AppComponent component; + + @Before + public void setUp() { + component = new AppComponent(); + component.activate(); + + } + + @After + public void tearDown() { + component.deactivate(); + } + + @Test + public void basics() { + + } + +} diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/archetype.properties b/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/archetype.properties new file mode 100644 index 00000000..a1213b40 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/archetype.properties @@ -0,0 +1,21 @@ +# +# Copyright 2014 Open Networking Laboratory +# +# 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. +# + +#Thu Dec 04 09:24:50 PST 2014 +package=it.pkg +version=0.1-SNAPSHOT +groupId=archetype.it +artifactId=basic diff --git a/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/goal.txt b/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/goal.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/bundle/src/test/resources/projects/basic/goal.txt diff --git a/framework/src/onos/tools/package/archetypes/cli/pom.xml b/framework/src/onos/tools/package/archetypes/cli/pom.xml new file mode 100644 index 00000000..1ab9c1f2 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/pom.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-archetypes</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>onos-cli-archetype</artifactId> + <packaging>maven-archetype</packaging> + + <name>onos-cli-archetype</name> + <description>ONOS Apache Karaf bundle archetype</description> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/cli/src/main/resources/META-INF/maven/archetype-metadata.xml b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 00000000..8558d476 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<archetype-descriptor + xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" + name="onos-cli" partial="true" + xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <fileSets> + <fileSet filtered="true" packaged="true" encoding="UTF-8"> + <directory>src/main/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + <fileSet filtered="true" packaged="false" encoding="UTF-8"> + <directory>src/main/resources</directory> + <includes> + <include>**/*.xml</include> + </includes> + </fileSet> + </fileSets> +</archetype-descriptor> diff --git a/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/pom.xml b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 00000000..cb3862c3 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>${groupId}</groupId> + <artifactId>${artifactId}</artifactId> + <version>${version}</version> + <packaging>bundle</packaging> + + <description>ONOS OSGi bundle archetype</description> + <url>http://onosproject.org</url> + + <properties> + <onos.version>1.3.0-SNAPSHOT</onos.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-osgi</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-cli</artifactId> + <version>${onos.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + <scope>test</scope> + <classifier>tests</classifier> + </dependency> + + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <version>4.3.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <version>1.9.8</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.console</artifactId> + <version>3.0.3</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <version>1.20.0</version> + <executions> + <execution> + <id>generate-scr-srcdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + <configuration> + <supportedProjectTypes> + <supportedProjectType>bundle</supportedProjectType> + <supportedProjectType>war</supportedProjectType> + </supportedProjectTypes> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/java/AppCommand.java b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/java/AppCommand.java new file mode 100644 index 00000000..9262b2e4 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/java/AppCommand.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; + +/** + * Sample Apache Karaf CLI command + */ +@Command(scope = "onos", name = "sample", + description = "Sample Apache Karaf CLI command") +public class AppCommand extends AbstractShellCommand { + + @Override + protected void execute() { + print("Hello %s", "World"); + } + +} diff --git a/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/resources/OSGI-INF/blueprint/shell-config.xml new file mode 100644 index 00000000..202ab9ed --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/main/resources/archetype-resources/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> + <command> + <action class="${package}.AppCommand"/> + </command> + </command-bundle> + +</blueprint> diff --git a/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/archetype.properties b/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/archetype.properties new file mode 100644 index 00000000..a1213b40 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/archetype.properties @@ -0,0 +1,21 @@ +# +# Copyright 2014 Open Networking Laboratory +# +# 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. +# + +#Thu Dec 04 09:24:50 PST 2014 +package=it.pkg +version=0.1-SNAPSHOT +groupId=archetype.it +artifactId=basic diff --git a/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/goal.txt b/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/goal.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/cli/src/test/resources/projects/basic/goal.txt diff --git a/framework/src/onos/tools/package/archetypes/pom.xml b/framework/src/onos/tools/package/archetypes/pom.xml new file mode 100644 index 00000000..2fd5f874 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-base</artifactId> + <version>1</version> + <relativePath>../../build/pom.xml</relativePath> + </parent> + + <groupId>org.onosproject</groupId> + <artifactId>onos-archetypes</artifactId> + <version>1.3.0-SNAPSHOT</version> + <packaging>pom</packaging> + + <description>ONOS archetypes project</description> + + <modules> + <module>api</module> + <module>bundle</module> + <module>cli</module> + <module>ui</module> + </modules> + + <build> + <extensions> + <extension> + <groupId>org.apache.maven.archetype</groupId> + <artifactId>archetype-packaging</artifactId> + <version>2.2</version> + </extension> + </extensions> + + <pluginManagement> + <plugins> + <plugin> + <artifactId>maven-archetype-plugin</artifactId> + <version>2.2</version> + </plugin> + </plugins> + </pluginManagement> + </build> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/ui/pom.xml b/framework/src/onos/tools/package/archetypes/ui/pom.xml new file mode 100644 index 00000000..ca7b2d87 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/pom.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-archetypes</artifactId> + <version>1.3.0-SNAPSHOT</version> + </parent> + + <artifactId>onos-ui-archetype</artifactId> + <packaging>maven-archetype</packaging> + + <description>ONOS UI overlay archetype</description> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/META-INF/maven/archetype-metadata.xml b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/META-INF/maven/archetype-metadata.xml new file mode 100644 index 00000000..309fd6ad --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<archetype-descriptor + xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" + name="onos-ui" partial="true" + xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <fileSets> + <fileSet filtered="true" packaged="true" encoding="UTF-8"> + <directory>src/main/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </fileSet> + <fileSet filtered="true" packaged="false" encoding="UTF-8"> + <directory>src/main/resources</directory> + <includes> + <include>**/*.html</include> + <include>**/*.js</include> + <include>**/*.css</include> + </includes> + </fileSet> + </fileSets> +</archetype-descriptor> diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/pom.xml b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 00000000..a6beae99 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>${groupId}</groupId> + <artifactId>${artifactId}</artifactId> + <version>${version}</version> + <packaging>bundle</packaging> + + <description>ONOS OSGi UI bundle archetype</description> + <url>http://onosproject.org</url> + + <properties> + <onos.version>1.3.0-SNAPSHOT</onos.version> + <!-- Uncomment to generate ONOS app from this module. + <onos.app.name>org.foo.app</onos.app.name> + <onos.app.origin>Foo, Inc.</onos.app.origin> + --> + </properties> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-osgi</artifactId> + <version>${onos.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${onos.version}</version> + <scope>test</scope> + <classifier>tests</classifier> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <version>1.9.8</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <version>1.20.0</version> + <executions> + <execution> + <id>generate-scr-srcdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + <configuration> + <supportedProjectTypes> + <supportedProjectType>bundle</supportedProjectType> + <supportedProjectType>war</supportedProjectType> + </supportedProjectTypes> + </configuration> + </plugin> + <plugin> + <groupId>org.onosproject</groupId> + <artifactId>onos-maven-plugin</artifactId> + <version>1.5</version> + <executions> + <execution> + <id>cfg</id> + <phase>generate-resources</phase> + <goals> + <goal>cfg</goal> + </goals> + </execution> + <execution> + <id>swagger</id> + <phase>generate-sources</phase> + <goals> + <goal>swagger</goal> + </goals> + </execution> + <execution> + <id>app</id> + <phase>package</phase> + <goals> + <goal>app</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiComponent.java b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiComponent.java new file mode 100644 index 00000000..f40bcb5f --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiComponent.java @@ -0,0 +1,76 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +import com.google.common.collect.ImmutableList; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.ui.UiExtension; +import org.onosproject.ui.UiExtensionService; +import org.onosproject.ui.UiMessageHandlerFactory; +import org.onosproject.ui.UiView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Skeletal ONOS UI application component. + */ +@Component(immediate = true) +public class AppUiComponent { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected UiExtensionService uiExtensionService; + + // List of application views + private final List<UiView> uiViews = ImmutableList.of( + new UiView(UiView.Category.OTHER, "sample", "Sample") + ); + + // Factory for UI message handlers + private final UiMessageHandlerFactory messageHandlerFactory = + () -> ImmutableList.of( + new AppUiMessageHandler() + ); + + // Application UI extension + protected UiExtension extension = + new UiExtension.Builder(getClass().getClassLoader(), uiViews) + .messageHandlerFactory(messageHandlerFactory) + .build(); + + @Activate + protected void activate() { + uiExtensionService.register(extension); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + uiExtensionService.unregister(extension); + log.info("Stopped"); + } + +} diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java new file mode 100644 index 00000000..d9d68b53 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/java/AppUiMessageHandler.java @@ -0,0 +1,189 @@ +#set( $symbol_pound = '#' ) +#set( $symbol_dollar = '$' ) +#set( $symbol_escape = '\' ) +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * 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. + */ +package ${package}; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableSet; +import org.onosproject.ui.RequestHandler; +import org.onosproject.ui.UiMessageHandler; +import org.onosproject.ui.table.TableModel; +import org.onosproject.ui.table.TableRequestHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.Override; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Skeletal ONOS UI message handler. + * <p> + * This example specifically supporting a "table" view. + */ +public class AppUiMessageHandler extends UiMessageHandler { + + private static final String SAMPLE_DATA_REQ = "sampleDataRequest"; + private static final String SAMPLE_DATA_RESP = "sampleDataResponse"; + private static final String SAMPLES = "samples"; + + private static final String SAMPLE_DETAIL_REQ = "sampleDetailsRequest"; + private static final String SAMPLE_DETAIL_RESP = "sampleDetailsResponse"; + private static final String DETAILS = "details"; + + private static final String ID = "id"; + private static final String LABEL = "label"; + private static final String CODE = "code"; + private static final String COMMENT = "comment"; + private static final String RESULT = "result"; + + private static final String[] COLUMN_IDS = { ID, LABEL, CODE }; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + + @Override + protected Collection<RequestHandler> createRequestHandlers() { + return ImmutableSet.of( + new SampleDataRequestHandler(), + new SampleDetailRequestHandler() + ); + } + + // handler for sample table requests + private final class SampleDataRequestHandler extends TableRequestHandler { + + private SampleDataRequestHandler() { + super(SAMPLE_DATA_REQ, SAMPLE_DATA_RESP, SAMPLES); + } + + // if necessary, override defaultColumnId() -- if it isn't "id" + + @Override + protected String[] getColumnIds() { + return COLUMN_IDS; + } + + @Override + protected void populateTable(TableModel tm, ObjectNode payload) { + // === set custom column cell formatters/comparators if need be... + // tm.setFormatter(CODE, new CodeFormatter()); + // tm.setComparator(CODE, new CodeComparator()); + + // === retrieve table row items from some service... + // SomeService ss = get(SomeService.class); + // List<Item> items = ss.getItems() + + // fake data for demonstration purposes... + List<Item> items = getItems(); + for (Item item: items) { + populateRow(tm.addRow(), item); + } + } + + private void populateRow(TableModel.Row row, Item item) { + row.cell(ID, item.id()) + .cell(LABEL, item.label()) + .cell(CODE, item.code()); + } + } + + + // handler for sample item details requests + private final class SampleDetailRequestHandler extends RequestHandler { + + private SampleDetailRequestHandler() { + super(SAMPLE_DETAIL_REQ); + } + + @Override + public void process(long sid, ObjectNode payload) { + String id = string(payload, ID, "(none)"); + + // SomeService ss = get(SomeService.class); + // Item item = ss.getItemDetails(id) + + // fake data for demonstration purposes... + Item item = getItem(id); + + ObjectNode rootNode = MAPPER.createObjectNode(); + ObjectNode data = MAPPER.createObjectNode(); + rootNode.set(DETAILS, data); + + if (item == null) { + rootNode.put(RESULT, "Item with id '" + id + "' not found"); + log.warn("attempted to get item detail for id '{}'", id); + + } else { + rootNode.put(RESULT, "Found item with id '" + id + "'"); + + data.put(ID, item.id()); + data.put(LABEL, item.label()); + data.put(CODE, item.code()); + data.put(COMMENT, "Some arbitrary comment"); + } + + sendMessage(SAMPLE_DETAIL_RESP, 0, rootNode); + } + } + + + // =================================================================== + // NOTE: The code below this line is to create fake data for this + // sample code. Normally you would use existing services to + // provide real data. + + // Lookup a single item. + private static Item getItem(String id) { + // We realize this code is really inefficient, but + // it suffices for our purposes of demonstration... + for (Item item : getItems()) { + if (item.id().equals(id)) { + return item; + } + } + return null; + } + + // Produce a list of items. + private static List<Item> getItems() { + List<Item> items = new ArrayList<>(); + items.add(new Item("item-1", "foo", 42)); + items.add(new Item("item-2", "bar", 99)); + items.add(new Item("item-3", "baz", 65)); + return items; + } + + // Simple model class to provide sample data + private static class Item { + private final String id; + private final String label; + private final int code; + + Item(String id, String label, int code) { + this.id = id; + this.label = label; + this.code = code; + } + + String id() { return id; } + String label() { return label; } + int code() { return code; } + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css new file mode 100644 index 00000000..c492e203 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.css @@ -0,0 +1,35 @@ +/* css for sample app view */ + +#ov-sample h2 { + display: inline-block; +} + +/* Panel Styling */ +#item-details-panel.floatpanel { + position: absolute; + top: 115px; +} + +.light #item-details-panel.floatpanel { + background-color: rgb(229, 234, 237); +} +.dark #item-details-panel.floatpanel { + background-color: #3A4042; +} + +#item-details-panel h3 { + margin: 0; + font-size: large; +} + +#item-details-panel h4 { + margin: 0; +} + +#item-details-panel td { + padding: 5px; +} +#item-details-panel td.label { + font-style: italic; + opacity: 0.8; +}
\ No newline at end of file diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html new file mode 100644 index 00000000..03a7383e --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.html @@ -0,0 +1,46 @@ +<!-- partial HTML --> +<div id="ov-sample"> + <div class="tabular-header"> + <h2>Items ({{tableData.length}} total)</h2> + <div class="ctrl-btns"> + <div class="refresh" ng-class="{active: autoRefresh}" + icon icon-id="refresh" icon-size="36" + tooltip tt-msg="autoRefreshTip" + ng-click="toggleRefresh()"></div> + </div> + </div> + + <div class="summary-list" onos-table-resize> + + <div class="table-header" onos-sortable-header> + <table> + <tr> + <td colId="id" sortable>Item ID </td> + <td colId="label" sortable>Label </td> + <td colId="code" sortable>Code </td> + </tr> + </table> + </div> + + <div class="table-body"> + <table> + <tr ng-if="!tableData.length" class="no-data"> + <td colspan="3"> + No Items found + </td> + </tr> + + <tr ng-repeat="item in tableData track by $index" + ng-click="selectCallback($event, item)" + ng-class="{selected: item.id === selId}"> + <td>{{item.id}}</td> + <td>{{item.label}}</td> + <td>{{item.code}}</td> + </tr> + </table> + </div> + + </div> + + <item-details-panel></item-details-panel> +</div> diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js new file mode 100644 index 00000000..2d4aed48 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/app/view/sample/sample.js @@ -0,0 +1,139 @@ +// js for sample app view +(function () { + 'use strict'; + + // injected refs + var $log, $scope, fs, wss, ps; + + // constants + var detailsReq = 'sampleDetailsRequest', + detailsResp = 'sampleDetailsResponse', + pName = 'item-details-panel', + + propOrder = ['id', 'label', 'code'], + friendlyProps = ['Item ID', 'Item Label', 'Special Code']; + + + function addProp(tbody, index, value) { + var tr = tbody.append('tr'); + + function addCell(cls, txt) { + tr.append('td').attr('class', cls).html(txt); + } + addCell('label', friendlyProps[index] + ' :'); + addCell('value', value); + } + + function populatePanel(panel) { + var title = panel.append('h3'), + tbody = panel.append('table').append('tbody'); + + title.text('Item Details'); + + propOrder.forEach(function (prop, i) { + addProp(tbody, i, $scope.panelDetails[prop]); + }); + + panel.append('hr'); + panel.append('h4').text('Comments'); + panel.append('p').text($scope.panelDetails.comment); + } + + function respDetailsCb(data) { + $scope.panelDetails = data.details; + $scope.$apply(); + } + + angular.module('ovSample', []) + .controller('OvSampleCtrl', + ['$log', '$scope', 'TableBuilderService', + 'FnService', 'WebSocketService', + + function (_$log_, _$scope_, tbs, _fs_, _wss_) { + $log = _$log_; + $scope = _$scope_; + fs = _fs_; + wss = _wss_; + + var handlers = {}; + $scope.panelDetails = {}; + + // details response handler + handlers[detailsResp] = respDetailsCb; + wss.bindHandlers(handlers); + + // custom selection callback + function selCb($event, row) { + if ($scope.selId) { + wss.sendEvent(detailsReq, { id: row.id }); + } else { + $scope.hidePanel(); + } + $log.debug('Got a click on:', row); + } + + // TableBuilderService creating a table for us + tbs.buildTable({ + scope: $scope, + tag: 'sample', + selCb: selCb + }); + + // cleanup + $scope.$on('$destroy', function () { + wss.unbindHandlers(handlers); + }); + + $log.log('OvSampleCtrl has been created'); + }]) + + .directive('itemDetailsPanel', ['PanelService', 'KeyService', + function (_ps_, ks) { + return { + restrict: 'E', + link: function (scope, element, attrs) { + ps = _ps_; + // insert details panel with PanelService + // create the panel + var panel = ps.createPanel(pName, { + width: 200, + margin: 20, + hideMargin: 0 + }); + panel.hide(); + scope.hidePanel = function () { panel.hide(); }; + + function closePanel() { + if (panel.isVisible()) { + $scope.selId = null; + panel.hide(); + } + } + + // create key bindings to handle panel + ks.keyBindings({ + esc: [closePanel, 'Close the details panel'], + _helpFormat: ['esc'] + }); + ks.gestureNotes([ + ['click', 'Select a row to show item details'] + ]); + + // update the panel's contents when the data is changed + scope.$watch('panelDetails', function () { + if (!fs.isEmptyObject(scope.panelDetails)) { + panel.empty(); + populatePanel(panel); + panel.show(); + } + }); + + // cleanup on destroyed scope + scope.$on('$destroy', function () { + ks.unbindKeys(); + ps.destroyPanel(pName); + }); + } + }; + }]); +}()); diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/css.html b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/css.html new file mode 100644 index 00000000..c4697256 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/css.html @@ -0,0 +1 @@ +<link rel="stylesheet" href="app/view/sample/sample.css">
\ No newline at end of file diff --git a/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/js.html b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/js.html new file mode 100644 index 00000000..7cacc707 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/main/resources/archetype-resources/src/main/resources/js.html @@ -0,0 +1 @@ +<script src="app/view/sample/sample.js"></script>
\ No newline at end of file diff --git a/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/archetype.properties b/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/archetype.properties new file mode 100644 index 00000000..a1213b40 --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/archetype.properties @@ -0,0 +1,21 @@ +# +# Copyright 2014 Open Networking Laboratory +# +# 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. +# + +#Thu Dec 04 09:24:50 PST 2014 +package=it.pkg +version=0.1-SNAPSHOT +groupId=archetype.it +artifactId=basic diff --git a/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/goal.txt b/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/goal.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/onos/tools/package/archetypes/ui/src/test/resources/projects/basic/goal.txt diff --git a/framework/src/onos/tools/package/bin/onos-client b/framework/src/onos/tools/package/bin/onos-client new file mode 100755 index 00000000..2a37087a --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-client @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS command-line client that uses the built-in Apache Karaf client. +# ----------------------------------------------------------------------------- + +if [ -z "${JAVA_HOME}" ]; then + if [ -x /usr/libexec/java_home ]; then + export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) + elif [ -d /usr/lib/jvm/java-8-oracle ]; then + export JAVA_HOME="/usr/lib/jvm/java-8-oracle" + elif [ -d /usr/lib/jvm/java-7-openjdk-amd64 ]; then + export JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64" + fi +fi + +cd $(dirname $0)/../apache-karaf-$KARAF_VERSION/bin +./client -h localhost -u karaf "$@" diff --git a/framework/src/onos/tools/package/bin/onos-config b/framework/src/onos/tools/package/bin/onos-config new file mode 100755 index 00000000..2265d002 --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-config @@ -0,0 +1,2 @@ +#!/bin/bash +echo "This command has been deprecated as this step is no longer required."
\ No newline at end of file diff --git a/framework/src/onos/tools/package/bin/onos-form-cluster b/framework/src/onos/tools/package/bin/onos-form-cluster new file mode 100755 index 00000000..7a0abda6 --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-form-cluster @@ -0,0 +1,39 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Forms ONOS cluster using REST API of each separate instance. +# ----------------------------------------------------------------------------- + +[ $# -lt 2 ] && echo "usage: $(basename $0) ip1 ip2..." && exit 1 + +# Scan arguments for user/password or other options... +while getopts u:p: o; do + case "$o" in + u) user=$OPTARG;; + p) password=$OPTARG;; + esac +done +user=${user:-onos} # user defaults to 'onos' +password=${password:-$user} # password defaults to user name if not specified +let OPC=$OPTIND-1 +shift $OPC + +ip=$1 +shift +nodes=$* + +ipPrefix=${ip%.*} + +aux=/tmp/${ipPrefix}.cluster.json +trap "rm -f $aux" EXIT + +echo "{ \"nodes\": [ { \"ip\": \"$ip\" }" > $aux +for node in $nodes; do + echo ", { \"ip\": \"$node\" }" >> $aux +done +echo "], \"ipPrefix\": \"$ipPrefix.*\" }" >> $aux + +for node in $ip $nodes; do + echo "Forming cluster on $node..." + curl --user $user:$password -X POST \ + http://$node:8181/onos/v1/cluster/configuration -d @$aux +done
\ No newline at end of file diff --git a/framework/src/onos/tools/package/bin/onos-jpenable b/framework/src/onos/tools/package/bin/onos-jpenable new file mode 100755 index 00000000..7c69602a --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-jpenable @@ -0,0 +1,7 @@ +#!/bin/bash + +kpid=$(ps -ef | grep karaf.main.Main | grep -v grep | cut -c10-15 | tr -d ' ') + +[ -z "$kpid" ] && echo "No ONOS!" && exit 1 + +/opt/jprofiler8/bin/jpenable --gui --port=8849 --pid=$kpid diff --git a/framework/src/onos/tools/package/bin/onos-secure-ssh b/framework/src/onos/tools/package/bin/onos-secure-ssh new file mode 100755 index 00000000..3f541dbe --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-secure-ssh @@ -0,0 +1,38 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Enables secure access to ONOS console by removing default users & keys. +# ----------------------------------------------------------------------------- + +rm -f $(dirname $0)/onos + +set -e + +# Scan arguments for user/password or other options... +while getopts u:p: o; do + case "$o" in + u) user=$OPTARG;; + p) password=$OPTARG;; + esac +done +password=${password:-$user} # password defaults to the user if not specified +let OPC=$OPTIND-1 +shift $OPC + +cd $(dirname $0)/../apache-karaf-*/etc +USERS=users.properties +KEYS=keys.properties + +# Remove the built-in users and keys to secure the access implicitly. +egrep -v "^(karaf|onos)[ ]*=" $USERS > $USERS.new && mv $USERS.new $USERS +egrep -v "^(#karaf|onos)[ ]*=" $KEYS > $KEYS.new && mv $KEYS.new $KEYS + +# Remove any previous known keys for the local host. +ssh-keygen -f "$HOME/.ssh/known_hosts" -R [localhost]:8101 + +# Swap the onos client to use the SSH variant. +ln -s $(dirname $0)/onos-ssh $(dirname $0)/onos + +# If user and password options were given, setup the user/password. +if [ -n "$user" -a -n "$password" ]; then + echo "$user = $password,_g_:admingroup" >> $USERS +fi
\ No newline at end of file diff --git a/framework/src/onos/tools/package/bin/onos-service b/framework/src/onos/tools/package/bin/onos-service new file mode 100755 index 00000000..2f00ca02 --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-service @@ -0,0 +1,44 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts ONOS Apache Karaf container +# ----------------------------------------------------------------------------- + +# uncomment the following line for performance testing +#export JAVA_OPTS="${JAVA_OPTS:--Xms8G -Xmx8G -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps}" + +# uncomment the following line for Netty TLS encryption +# Do modify the keystore location/password and truststore location/password accordingly +#export JAVA_OPTS="${JAVA_OPTS:--DenableNettyTLS=true -Djavax.net.ssl.keyStore=/home/ubuntu/onos.jks -Djavax.net.ssl.keyStorePassword=222222 -Djavax.net.ssl.trustStore=/home/ubuntu/onos.jks -Djavax.net.ssl.trustStorePassword=222222}" + +ONOS_HOME=/opt/onos +KARAF_ARGS= +SYS_APPS=drivers + +[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/.. + +# Parse out arguments destinted for karaf invocation v. arguments that +# will be processed in line +while [ $# -gt 0 ]; do + case $1 in + apps-clean) + # Deactivate all applications + find ${ONOS_HOME}/apps -name "active" -exec rm \{\} \; + ;; + *) + KARAF_ARGS+=" $1" + ;; + esac + shift +done + +# Activate the system required applications (SYS_APPS) as well as any +# specified applications in the var ONOS_APPS +for app in ${SYS_APPS//,/ } ${ONOS_APPS//,/ }; do + if [[ "$app" =~ \. ]]; then + touch ${ONOS_HOME}/apps/$app/active + else + touch ${ONOS_HOME}/apps/org.onosproject.$app/active + fi +done + +exec ${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf $KARAF_ARGS diff --git a/framework/src/onos/tools/package/bin/onos-ssh b/framework/src/onos/tools/package/bin/onos-ssh new file mode 100755 index 00000000..7e082aa5 --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-ssh @@ -0,0 +1,6 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS command-line client that uses raw ssh. +# ----------------------------------------------------------------------------- + +ssh -p 8101 localhost "$@"
\ No newline at end of file diff --git a/framework/src/onos/tools/package/bin/onos-user-key b/framework/src/onos/tools/package/bin/onos-user-key new file mode 100755 index 00000000..db24da17 --- /dev/null +++ b/framework/src/onos/tools/package/bin/onos-user-key @@ -0,0 +1,20 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Adds or removes a user key for managing passwordless loging to ONOS console. +# ----------------------------------------------------------------------------- + +[ $# -lt 2 ] && echo "usage: $(basename $0) user {key|remove}" && exit 1 + +set -e + +user=$1 +[ -f $2 ] && key=$(cut -d\ -f2 $2) || key=$2 + +cd $(dirname $0)/../apache-karaf-*/etc +KEYS=keys.properties + +# Remove the user key first, in case one was already present +egrep -v "^$user[ ]*=" $KEYS > $KEYS.new && mv $KEYS.new $KEYS +if [ $key != "remove" ]; then + echo "$user=$key,_g_:admingroup" >> $KEYS +fi diff --git a/framework/src/onos/tools/package/branding/pom.xml b/framework/src/onos/tools/package/branding/pom.xml new file mode 100644 index 00000000..452a03c9 --- /dev/null +++ b/framework/src/onos/tools/package/branding/pom.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../../../pom.xml</relativePath> + </parent> + + <artifactId>onos-branding</artifactId> + <packaging>bundle</packaging> + <description>Custom Karaf CLI motd</description> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>manual</Bundle-SymbolicName> + <Import-Package>*</Import-Package> + <Private-Package>!*</Private-Package> + <Export-Package> + org.apache.karaf.branding + </Export-Package> + <Spring-Context>*;public-context:=false</Spring-Context> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> + diff --git a/framework/src/onos/tools/package/branding/src/main/resources/org/apache/karaf/branding/branding.properties b/framework/src/onos/tools/package/branding/src/main/resources/org/apache/karaf/branding/branding.properties new file mode 100644 index 00000000..7a9f9f2d --- /dev/null +++ b/framework/src/onos/tools/package/branding/src/main/resources/org/apache/karaf/branding/branding.properties @@ -0,0 +1,26 @@ +# +# Copyright 2014 Open Networking Laboratory +# +# 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. +# +welcome = Welcome to Open Network Operating System (ONOS)!\r\n\ +\u001B[1;31m ____ _ ______ ____ \u001B[0m\r\n\ +\u001B[1;31m / __ \\/ |/ / __ \\/ __/ \u001B[0m\r\n\ +\u001B[1;31m / /_/ / / /_/ /\\ \\ \u001B[0m\r\n\ +\u001B[1;31m \\____/_/|_/\\____/___/ \u001B[0m\r\n\ +\u001B[1;31m \u001B[0m\r\n\ + \r\n\ + Hit '\u001B[1m<tab>\u001B[0m' for a list of available commands\r\n\ + and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\r\n\ + Hit '\u001B[1m<ctrl-d>\u001B[0m' or type '\u001B[1msystem:shutdown\u001B[0m' or '\u001B[1mlogout\u001B[0m' to shutdown ONOS.\r\n +prompt = \u001B[32monos> \u001B[0m diff --git a/framework/src/onos/tools/package/config/README b/framework/src/onos/tools/package/config/README new file mode 100644 index 00000000..970f87a5 --- /dev/null +++ b/framework/src/onos/tools/package/config/README @@ -0,0 +1,2 @@ +The onos-config command will copy files contained in this directory to ONOS +instances according to cell definition. diff --git a/framework/src/onos/tools/package/config/samples/segmentrouting.conf b/framework/src/onos/tools/package/config/samples/segmentrouting.conf new file mode 100644 index 00000000..8df6c3d2 --- /dev/null +++ b/framework/src/onos/tools/package/config/samples/segmentrouting.conf @@ -0,0 +1,78 @@ +{ + "comment": " Multilayer topology description and configuration", + "restrictSwitches": true, + "restrictLinks": true, + + "switchConfig": + [ + { "nodeDpid" : "of:0000000000000001", "name": "Dallas-R1", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.1/32", + "routerMac": "00:00:01:01:01:80", + "nodeSid": 101, + "isEdgeRouter" : true, + "adjacencySids": [ + { "ports": [ 4, 5 ], "adjSid": 10234 }, + { "ports": [ 6, 7 ], "adjSid": 29019 } + ], + "subnets": [ + { "portNo": 1, "subnetIp": "10.0.1.128/24" } + ] + } + }, + + { "nodeDpid": "of:0000000000000002", "name": "Dallas-R2", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.2/32", + "routerMac": "00:00:02:02:02:80", + "nodeSid": 102, + "isEdgeRouter" : false, + "adjacencySids": [ + { "ports": [ 1, 2 ], "adjSid": 12453 }, + { "ports": [ 2, 3 ], "adjSid": 23333 }, + { "ports": [ 3, 1 ], "adjSid": 22233 } + ] + } + }, + + { "nodeDpid": "of:0000000000000003", "name": "Dallas-R3", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.3/32", + "routerMac": "00:00:03:03:03:80", + "nodeSid": 103, + "isEdgeRouter" : false + } + }, + + { "nodeDpid": "of:0000000000000004", "name": "Dallas-R4", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.4/32", + "routerMac": "00:00:04:04:04:80", + "nodeSid": 104, + "isEdgeRouter" : false + } + }, + + { "nodeDpid": "of:0000000000000005", "name": "Dallas-R5", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.5/32", + "routerMac": "00:00:05:05:05:80", + "nodeSid": 105, + "isEdgeRouter" : false + } + }, + + { "nodeDpid": "of:0000000000000006", "name": "Dallas-R6", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.6/32", + "routerMac": "00:00:07:07:07:80", + "nodeSid": 106, + "isEdgeRouter" : true, + "subnets": [ + { "portNo": 1, "subnetIp": "7.7.7.128/24" } + ] + } + } + + ] +} diff --git a/framework/src/onos/tools/package/config/samples/segmentrouting_dell.conf b/framework/src/onos/tools/package/config/samples/segmentrouting_dell.conf new file mode 100644 index 00000000..be489a65 --- /dev/null +++ b/framework/src/onos/tools/package/config/samples/segmentrouting_dell.conf @@ -0,0 +1,93 @@ +{ + "comment": " Multilayer topology description and configuration", + "restrictSwitches": true, + "restrictLinks": true, + + "switchConfig": + [ + { "nodeDpid" : "of:00010001e88b9368", "name": "Dell-R1", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.1/32", + "routerMac": "00:01:e8:8b:93:6b", + "nodeSid": 101, + "isEdgeRouter" : true, + "subnets": [ + { "portNo": 46, "subnetIp": "10.200.1.1/24" } + ] + } + }, + + { "nodeDpid": "of:00010001e88b939b", "name": "Dell-R2", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.2/32", + "routerMac": "00:01:e8:8b:93:9e", + "nodeSid": 102, + "isEdgeRouter" : true, + "subnets": [ + { "portNo": 46, "subnetIp": "10.200.2.1/24" } + ] + } + }, + + { "nodeDpid": "of:00010001e88b938c", "name": "Dell-R3", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.3/32", + "routerMac": "00:01:e8:8b:93:8f", + "nodeSid": 103, + "isEdgeRouter" : true, + "subnets": [ + { "portNo": 46, "subnetIp": "10.200.3.1/24" } + ] + } + }, + + { "nodeDpid": "of:00010001e88b93ad", "name": "Dell-R4", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.4/32", + "routerMac": "00:01:e8:8b:93:b0", + "nodeSid": 104, + "isEdgeRouter" : true, + "subnets": [ + { "portNo": 46, "subnetIp": "10.200.4.1/24" } + ] + } + }, + + { "nodeDpid": "of:00010001e88b93bc", "name": "Dell-R5", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.5/32", + "routerMac": "00:01:e8:8b:93:bf", + "nodeSid": 105, + "isEdgeRouter" : false + } + }, + + { "nodeDpid": "of:00010001e88b93c2", "name": "Dell-R6", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.6/32", + "routerMac": "00:01:e8:8b:93:c5", + "nodeSid": 106, + "isEdgeRouter" : false + } + }, + + { "nodeDpid": "of:00010001e88b9398", "name": "Dell-R7", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.7/32", + "routerMac": "00:01:e8:8b:93:9b", + "nodeSid": 107, + "isEdgeRouter": false + } + }, + + { "nodeDpid": "of:00010001e88b27e3", "name": "Dell-R8", "type": "Router_SR", "allowed": true, + "latitude": 80.80, "longitude": 90.10, + "params": { "routerIp": "192.168.0.8/32", + "routerMac": "00:01:e8:8b:27:e6", + "nodeSid": 108, + "isEdgeRouter": false + } + } + + ] +} diff --git a/framework/src/onos/tools/package/debian/onos.conf b/framework/src/onos/tools/package/debian/onos.conf new file mode 100644 index 00000000..634a2636 --- /dev/null +++ b/framework/src/onos/tools/package/debian/onos.conf @@ -0,0 +1,27 @@ +description "Open Network Operating System" +author "ON.Lab" + +start on (net-device-up + and local-filesystems + and runlevel [2345]) +stop on runlevel [016] + +console output +kill timeout 60 +respawn + +env LANG=en_US.UTF-8 +#env JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 +#env NEW_JAVA_HOME=/usr/lib/jvm/java-8-oracle/ + +pre-stop script + /opt/onos/bin/onos halt 2>>/opt/onos/var/stderr.log + sleep 1 +end script + +script + [ -f /opt/onos/options ] && . /opt/onos/options + start-stop-daemon --signal INT --start --chuid $ONOS_USER \ + --exec /opt/onos/bin/onos-service -- $ONOS_OPTS \ + >/opt/onos/var/stdout.log 2>/opt/onos/var/stderr.log +end script diff --git a/framework/src/onos/tools/package/etc/org.ops4j.pax.url.mvn.cfg b/framework/src/onos/tools/package/etc/org.ops4j.pax.url.mvn.cfg new file mode 100644 index 00000000..15167a3b --- /dev/null +++ b/framework/src/onos/tools/package/etc/org.ops4j.pax.url.mvn.cfg @@ -0,0 +1,101 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# +################################################################################ + +# +# If set to true, the following property will not allow any certificate to be used +# when accessing Maven repositories through SSL +# +#org.ops4j.pax.url.mvn.certificateCheck= + +# +# Path to the local Maven settings file. +# The repositories defined in this file will be automatically added to the list +# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property +# below is not set. +# The following locations are checked for the existence of the settings.xml file +# * 1. looks for the specified url +# * 2. if not found looks for ${user.home}/.m2/settings.xml +# * 3. if not found looks for ${maven.home}/conf/settings.xml +# * 4. if not found looks for ${M2_HOME}/conf/settings.xml +# +#org.ops4j.pax.url.mvn.settings= + +# +# Path to the local Maven repository which is used to avoid downloading +# artifacts when they already exist locally. +# The value of this property will be extracted from the settings.xml file +# above, or defaulted to: +# System.getProperty( "user.home" ) + "/.m2/repository" +# +#org.ops4j.pax.url.mvn.localRepository= + +# +# Default this to false. It's just weird to use undocumented repos +# +org.ops4j.pax.url.mvn.useFallbackRepositories=false + +# +# Uncomment if you don't wanna use the proxy settings +# from the Maven conf/settings.xml file +# +# org.ops4j.pax.url.mvn.proxySupport=false + +# +# Comma separated list of repositories scanned when resolving an artifact. +# Those repositories will be checked before iterating through the +# below list of repositories and even before the local repository +# A repository url can be appended with zero or more of the following flags: +# @snapshots : the repository contains snaphots +# @noreleases : the repository does not contain any released artifacts +# +# The following property value will add the system folder as a repo. +# +org.ops4j.pax.url.mvn.defaultRepositories=\ + file:${karaf.home}/${karaf.default.repository}@id=system.repository@snapshots,\ + file:${karaf.data}/kar@id=kar.repository@multi@snapshots + +# Use the default local repo (e.g.~/.m2/repository) as a "remote" repo +#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false + +# +# Comma separated list of repositories scanned when resolving an artifact. +# The default list includes the following repositories: +# http://repo1.maven.org/maven2@id=central +# http://repository.springsource.com/maven/bundles/release@id=spring.ebr +# http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external +# http://zodiac.springsource.com/maven/bundles/release@id=gemini +# http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases +# https://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@noreleases +# https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases +# To add repositories to the default ones, prepend '+' to the list of repositories +# to add. +# A repository url can be appended with zero or more of the following flags: +# @snapshots : the repository contains snapshots +# @noreleases : the repository does not contain any released artifacts +# @id=repository.id : the id for the repository, just like in the settings.xml this is optional but recommended +# +org.ops4j.pax.url.mvn.repositories= \ + ${org.ops4j.pax.url.mvn.defaultRepositories}, \ + http://repo1.maven.org/maven2@id=central, \ + http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, \ + http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, \ + http://zodiac.springsource.com/maven/bundles/release@id=gemini, \ + http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases, \ + https://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@noreleases, \ + https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases diff --git a/framework/src/onos/tools/package/etc/org.ops4j.pax.web.cfg b/framework/src/onos/tools/package/etc/org.ops4j.pax.web.cfg new file mode 100644 index 00000000..c8fb3b3d --- /dev/null +++ b/framework/src/onos/tools/package/etc/org.ops4j.pax.web.cfg @@ -0,0 +1,12 @@ +org.osgi.service.http.port=8181 +org.osgi.service.http.port.secure=8443 + +org.osgi.service.http.enabled=true +org.osgi.service.http.secure.enabled=false + +org.ops4j.pax.web.ssl.keystore=etc/keystore +org.ops4j.pax.web.ssl.password=OBF:1xtn1w1u1uob1xtv1y7z1xtn1unn1w1o1xtv +org.ops4j.pax.web.ssl.keypassword=OBF:1xtn1w1u1uob1xtv1y7z1xtn1unn1w1o1xtv + +org.ops4j.pax.web.session.url=none +org.ops4j.pax.web.config.file=./etc/jetty.xml diff --git a/framework/src/onos/tools/package/etc/samples/linkGraph.cfg b/framework/src/onos/tools/package/etc/samples/linkGraph.cfg new file mode 100644 index 00000000..41ce5bdc --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/linkGraph.cfg @@ -0,0 +1,27 @@ +# NullLinkProvider topology description (config file). +# +# Dot-style topology graph. Each controller's topology begins with +# +# graph <node ID>, followed by a list of links between braces. +# +# The links are either bidirectional (--) or directed (->). The directed +# edges are used to connect together Null devices of different controllers. +# The endpoint has the format: +# +# devID:port:NodeId +# +# The NodeId is only added if the destination is another node's device. +# +graph 192.168.56.20 { + 0:0 -- 1:0 + 1:1 -> 0:0:192.168.56.30 + 1:2 -- 2:0 + 2:1 -> 1:0:192.168.56.30 +} +graph 192.168.56.30 { + 0:0 -> 1:1:192.168.56.20 + 0:1 -- 1:1 + 1:0 -> 2:1:192.168.56.20 + 1:2 -- 2:0 +} +# Bugs: Comments cannot be appended to a line to be read. diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.fwd.ReactiveForwarding.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.fwd.ReactiveForwarding.cfg new file mode 100644 index 00000000..4befc706 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.fwd.ReactiveForwarding.cfg @@ -0,0 +1,79 @@ +# +# Sample configuration for onos-app-fwd. +# + +# +# Reactive flows default matching is InPort, Src MAC, Dst MAC and EtherType fields +# + +# +# Enable packet-out only forwarding. +# This flag affects to both IPv4 and IPv6. +# +# packetOutOnly = true + +# +# Enable forwarding of the first packet by using OFPP_TABLE port in the +# PacketOut message instead of sending it directly to the switch port +# +# packetOutOfppTable = true + +# +# Timeout of reactively installed flows (in seconds). +# Default is 10 sec +# +# flowTimeout = 10 + +# +# Priority of reactively installed flows +# +# flowPriority = 10 + +# +# Enable IPv6 forwarding. +# +# ipv6Forwarding = true + +# +# Flows matching destination MAC only - as legacy L2 switches +# - This option overrides all other options below +# +# matchDstMacOnly = true + +# +# Matching of VLAN ID in Ethernet header +# +# matchVlanId = true + +# +# Matching of IPv4 addresses and Protocol field +# - must be enabled to match IPv4 DSCP, TCP/UDP ports and ICMP type/code +# +# matchIpv4Address = true + +# +# Matching of IPv4 DSCP and ECN fields +# +# matchIpv4Dscp = true + +# +# Matching of IPv6 addresses and Next-Header field +# - must be enabled to match IPv6 Flow Label, TCP/UDP ports and ICMP type/code +# +# matchIpv6Address = true + +# +# Matching of IPv6 Flow Label +# +# matchIpv6FlowLabel = true + +# +# Matching of TCP/UDP ports for IPv4 and IPv6 +# +# matchTcpUdpPorts = true + +# +# Matching of ICMP Type and Code fields for IPv4 and IPv6 +# +# matchIcmpFields = true + diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.host.impl.HostLocationProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.host.impl.HostLocationProvider.cfg new file mode 100644 index 00000000..6d3a50d9 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.host.impl.HostLocationProvider.cfg @@ -0,0 +1,13 @@ +# +# Sample configuration for Host Location Provider +# + +# +# Enable host removal on port/device down events. +# +# hostRemovalEnabled = true + +# +# Enable using IPv6 Neighbor Discovery by the Host Location Provider. +# +# ipv6NeighborDiscovery = true diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg new file mode 100644 index 00000000..6eb39a11 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg @@ -0,0 +1,21 @@ +# +# Sample configuration for link discovery +# + +# +# Disable Link Dicovery Permanently (Note: changing this property at runtime will have NO effect) +# WARNING: This should only be used for special projects like bgprouter, where ONOS is controlling +# a single switch +# +#disableLinkDiscovery = true + +# +# Enable Broadcast Discovery Protocol (EthType=0x8942) +# +#useBDDP = false + +# +# Disable LLDP's received from specific devices +# Details of the devices are in the file configured below +# +#lldpSuppression = ../config/lldp_suppresion.json diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.netconf.device.impl.NetconfDeviceProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.netconf.device.impl.NetconfDeviceProvider.cfg new file mode 100644 index 00000000..30ed0c26 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.netconf.device.impl.NetconfDeviceProvider.cfg @@ -0,0 +1,11 @@ +# +# Instance-specific configurations, in this case, the number of +# devices per node. +# +devConfigs = cisco:cisco@192.168.56.20:2022:inactive,sdn:rocks@192.168.56.30:22:inactive + +# +# Number of ports per device. This is global to all devices +# on all instances. +# +# numPorts = 8 diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg new file mode 100644 index 00000000..194bf037 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg @@ -0,0 +1,11 @@ +# +# Instance-specific configurations, in this case, the number of +# devices per node. +# +devConfigs = 192.168.56.20:3,192.168.56.30:3 + +# +# Number of ports per device. This is global to all devices +# on all instances. +# +# numPorts = 8 diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg new file mode 100644 index 00000000..ef72b1ee --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg @@ -0,0 +1,16 @@ +# +# Sample configurations for the NullLinkProvider. +# + +# +# If enabled, sets the time between LinkEvent generation, +# in microseconds. +# + +#eventRate = 1000000 + +# +# If enabled, points to the full path to the topology file. +# + +#cfgFile = /tmp/foo.cfg diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.packet.impl.NullPacketProvider.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.packet.impl.NullPacketProvider.cfg new file mode 100644 index 00000000..db4342c0 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.provider.nil.packet.impl.NullPacketProvider.cfg @@ -0,0 +1,4 @@ +# +# Uncomment and tweak to tune the rate of Packet events (per second) +# +# pktRate = 100 diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.proxyarp.ProxyArp.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.proxyarp.ProxyArp.cfg new file mode 100644 index 00000000..108de136 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.proxyarp.ProxyArp.cfg @@ -0,0 +1,8 @@ +# +# Sample configuration for onos-app-proxyarp. +# + +# +# Enable IPv6 Neighbor Discovery. +# +# ipv6NeighborDiscovery = true diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.routing.bgp.BgpSessionManager.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.routing.bgp.BgpSessionManager.cfg new file mode 100644 index 00000000..fbcc13f9 --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.routing.bgp.BgpSessionManager.cfg @@ -0,0 +1,8 @@ +# +# Sample configuration for onos-app-sdnip. +# + +# +# The port number that SDN-IP listens for incoming BGP connections on. +# +# bgpPort=2000
\ No newline at end of file diff --git a/framework/src/onos/tools/package/etc/samples/org.onosproject.xos.XOS.cfg b/framework/src/onos/tools/package/etc/samples/org.onosproject.xos.XOS.cfg new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/onos/tools/package/etc/samples/org.onosproject.xos.XOS.cfg diff --git a/framework/src/onos/tools/package/etc/users.properties b/framework/src/onos/tools/package/etc/users.properties new file mode 100644 index 00000000..9f7a2667 --- /dev/null +++ b/framework/src/onos/tools/package/etc/users.properties @@ -0,0 +1,34 @@ +################################################################################ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# +################################################################################ + +# +# This file contains the users, groups, and roles. +# Each line has to be of the format: +# +# USER=PASSWORD,ROLE1,ROLE2,... +# USER=PASSWORD,_g_:GROUP,... +# _g_\:GROUP=ROLE1,ROLE2,... +# +# All users, grousp, and roles entered in this file are available after Karaf startup +# and modifiable via the JAAS command group. These users reside in a JAAS domain +# with the name "karaf". +# +karaf = karaf,_g_:admingroup +onos = rocks,_g_:admingroup +_g_\:admingroup = group,admin,manager,viewer,webconsole diff --git a/framework/src/onos/tools/package/maven-plugin/pom.xml b/framework/src/onos/tools/package/maven-plugin/pom.xml new file mode 100644 index 00000000..54839b11 --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/pom.xml @@ -0,0 +1,122 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<project> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-base</artifactId> + <version>1</version> + <relativePath>../../build/pom.xml</relativePath> + </parent> + + <artifactId>onos-maven-plugin</artifactId> + <version>1.6-SNAPSHOT</version> + <packaging>maven-plugin</packaging> + + <description>Maven plugin for packaging ONOS applications or generating + component configuration resources + </description> + + <dependencies> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>2.0</version> + </dependency> + + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>2.0</version> + </dependency> + + <dependency> + <groupId>com.thoughtworks.qdox</groupId> + <artifactId>qdox</artifactId> + <version>2.0-M3</version> + </dependency> + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>18.0</version> + </dependency> + + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>3.2.1</version> + </dependency> + + <dependency> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>1.10</version> + </dependency> + + <!-- dependencies to annotations --> + <dependency> + <groupId>org.apache.maven.plugin-tools</groupId> + <artifactId>maven-plugin-annotations</artifactId> + <version>3.4</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.4.2</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + <version>2.4.2</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>3.4</version> + <executions> + <execution> + <id>default-descriptor</id> + <phase>process-classes</phase> + </execution> + <!-- if you want to generate help goal --> + <execution> + <id>help-goal</id> + <goals> + <goal>helpmojo</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java new file mode 100644 index 00000000..bfc6127a --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosAppMojo.java @@ -0,0 +1,372 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * 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. + */ +package org.onosproject.maven; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static com.google.common.io.ByteStreams.toByteArray; +import static org.codehaus.plexus.util.FileUtils.*; + +/** + * Produces ONOS application archive using the app.xml file information. + */ +@Mojo(name = "app", defaultPhase = LifecyclePhase.PACKAGE) +public class OnosAppMojo extends AbstractMojo { + + private static final String APP = "app"; + private static final String NAME = "[@name]"; + private static final String VERSION = "[@version]"; + private static final String FEATURES_REPO = "[@featuresRepo]"; + private static final String ARTIFACT = "artifact"; + + private static final String APP_XML = "app.xml"; + private static final String FEATURES_XML = "features.xml"; + + private static final String MVN_URL = "mvn:"; + private static final String M2_PREFIX = "m2"; + + private static final String ONOS_APP_NAME = "onos.app.name"; + private static final String ONOS_APP_ORIGIN = "onos.app.origin"; + + private static final String JAR = "jar"; + private static final String XML = "xml"; + private static final String APP_ZIP = "oar"; + private static final String PACKAGE_DIR = "oar"; + + private static final String DEFAULT_ORIGIN = "ON.Lab"; + private static final String DEFAULT_VERSION = "${project.version}"; + + private static final String DEFAULT_FEATURES_REPO = + "mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"; + private static final String DEFAULT_ARTIFACT = + "mvn:${project.groupId}/${project.artifactId}/${project.version}"; + + private static final int BUFFER_SIZE = 8192; + + private String name; + private String origin; + private String version = DEFAULT_VERSION; + private String featuresRepo = DEFAULT_FEATURES_REPO; + private List<String> artifacts; + + /** + * The project base directory. + */ + @Parameter(defaultValue = "${basedir}") + protected File baseDir; + + /** + * The directory where the generated catalogue file will be put. + */ + @Parameter(defaultValue = "${project.build.directory}") + protected File dstDirectory; + + /** + * The project group ID. + */ + @Parameter(defaultValue = "${project.groupId}") + protected String projectGroupId; + + /** + * The project artifact ID. + */ + @Parameter(defaultValue = "${project.artifactId}") + protected String projectArtifactId; + + /** + * The project version. + */ + @Parameter(defaultValue = "${project.version}") + protected String projectVersion; + + /** + * The project version. + */ + @Parameter(defaultValue = "${project.description}") + protected String projectDescription; + + @Parameter(defaultValue = "${localRepository}") + protected ArtifactRepository localRepository; + + /** + * Maven project + */ + @Parameter(defaultValue = "${project}") + protected MavenProject project; + + /** + * Maven project helper. + */ + @Component + protected MavenProjectHelper projectHelper; + + + private File m2Directory; + protected File stageDirectory; + protected String projectPath; + + @Override + public void execute() throws MojoExecutionException { + File appFile = new File(baseDir, APP_XML); + File featuresFile = new File(baseDir, FEATURES_XML); + + name = (String) project.getProperties().get(ONOS_APP_NAME); + + // If neither the app.xml file exists, nor the onos.app.name property + // is defined, there is nothing for this Mojo to do, so bail. + if (!appFile.exists() && name == null) { + return; + } + + m2Directory = new File(localRepository.getBasedir()); + stageDirectory = new File(dstDirectory, PACKAGE_DIR); + projectPath = M2_PREFIX + "/" + artifactDir(projectGroupId, projectArtifactId, projectVersion); + + origin = (String) project.getProperties().get(ONOS_APP_ORIGIN); + origin = origin != null ? origin : DEFAULT_ORIGIN; + + if (appFile.exists()) { + loadAppFile(appFile); + } else { + artifacts = ImmutableList.of(eval(DEFAULT_ARTIFACT)); + } + + // If there are any artifacts, stage the + if (!artifacts.isEmpty()) { + getLog().info("Building ONOS application package for " + name + " (v" + eval(version) + ")"); + artifacts.forEach(a -> getLog().debug("Including artifact: " + a)); + + if (stageDirectory.exists() || stageDirectory.mkdirs()) { + processAppXml(appFile); + processFeaturesXml(featuresFile); + processArtifacts(); + generateAppPackage(); + } else { + throw new MojoExecutionException("Unable to create directory: " + stageDirectory); + } + } + } + + // Loads the app.xml file. + private void loadAppFile(File appFile) throws MojoExecutionException { + XMLConfiguration xml = new XMLConfiguration(); + xml.setRootElementName(APP); + + try (FileInputStream stream = new FileInputStream(appFile)) { + xml.load(stream); + xml.setAttributeSplittingDisabled(true); + xml.setDelimiterParsingDisabled(true); + + name = xml.getString(NAME); + version = eval(xml.getString(VERSION)); + featuresRepo = eval(xml.getString(FEATURES_REPO)); + + artifacts = xml.configurationsAt(ARTIFACT).stream() + .map(cfg -> eval(cfg.getRootNode().getValue().toString())) + .collect(Collectors.toList()); + + } catch (ConfigurationException e) { + throw new MojoExecutionException("Unable to parse app.xml file", e); + } catch (FileNotFoundException e) { + throw new MojoExecutionException("Unable to find app.xml file", e); + } catch (IOException e) { + throw new MojoExecutionException("Unable to read app.xml file", e); + } + } + + // Processes and stages the app.xml file. + private void processAppXml(File appFile) throws MojoExecutionException { + try { + File file = new File(stageDirectory, APP_XML); + forceMkdir(stageDirectory); + String contents; + + if (appFile.exists()) { + contents = fileRead(appFile); + } else { + byte[] bytes = toByteArray(getClass().getResourceAsStream(APP_XML)); + contents = new String(bytes); + } + fileWrite(file.getAbsolutePath(), eval(contents)); + } catch (IOException e) { + throw new MojoExecutionException("Unable to process app.xml", e); + } + } + + private void processFeaturesXml(File featuresFile) throws MojoExecutionException { + boolean specified = featuresRepo != null && featuresRepo.length() > 0; + + // If featuresRepo attribute is specified and there is a features.xml + // file present, add the features repo as an artifact + try { + if (specified && featuresFile.exists()) { + processFeaturesXml(new FileInputStream(featuresFile)); + } else if (specified) { + processFeaturesXml(getClass().getResourceAsStream(FEATURES_XML)); + } + } catch (FileNotFoundException e) { + throw new MojoExecutionException("Unable to find features.xml file", e); + } catch (IOException e) { + throw new MojoExecutionException("Unable to process features.xml file", e); + } + } + + // Processes and stages the features.xml file. + private void processFeaturesXml(InputStream stream) throws IOException { + String featuresArtifact = + artifactFile(projectArtifactId, projectVersion, XML, "features"); + File dstDir = new File(stageDirectory, projectPath); + forceMkdir(dstDir); + String s = eval(new String(toByteArray(stream))); + fileWrite(new File(dstDir, featuresArtifact).getAbsolutePath(), s); + } + + // Stages all artifacts. + private void processArtifacts() throws MojoExecutionException { + for (String artifact : artifacts) { + processArtifact(artifact); + } + } + + // Stages the specified artifact. + private void processArtifact(String artifact) throws MojoExecutionException { + if (!artifact.startsWith(MVN_URL)) { + throw new MojoExecutionException("Unsupported artifact URL:" + artifact); + } + + String[] fields = artifact.substring(4).split("/"); + if (fields.length < 3) { + throw new MojoExecutionException("Illegal artifact URL:" + artifact); + } + + try { + String file = artifactFile(fields); + + if (projectGroupId.equals(fields[0]) && projectArtifactId.equals(fields[1])) { + // Local artifact is not installed yet, package it from target directory. + File dstDir = new File(stageDirectory, projectPath); + forceMkdir(dstDir); + copyFile(new File(dstDirectory, file), new File(dstDir, file)); + } else { + // Other artifacts are packaged from ~/.m2/repository directory. + String m2Path = artifactDir(fields); + File srcDir = new File(m2Directory, m2Path); + File dstDir = new File(stageDirectory, M2_PREFIX + "/" + m2Path); + forceMkdir(dstDir); + copyFile(new File(srcDir, file), new File(dstDir, file)); + } + } catch (IOException e) { + throw new MojoExecutionException("Unable to stage artifact " + artifact, e); + } + } + + // Generates the ONOS package ZIP file. + private void generateAppPackage() throws MojoExecutionException { + File appZip = new File(dstDirectory, artifactFile(projectArtifactId, projectVersion, + APP_ZIP, null)); + try (FileOutputStream fos = new FileOutputStream(appZip); + ZipOutputStream zos = new ZipOutputStream(fos)) { + zipDirectory("", stageDirectory, zos); + projectHelper.attachArtifact(this.project, APP_ZIP, null, appZip); + } catch (IOException e) { + throw new MojoExecutionException("Unable to compress application package", e); + } + } + + // Generates artifact directory name from the specified fields. + private String artifactDir(String[] fields) { + return artifactDir(fields[0], fields[1], fields[2]); + } + + // Generates artifact directory name from the specified elements. + private String artifactDir(String gid, String aid, String version) { + return gid.replace('.', '/') + "/" + aid.replace('.', '/') + "/" + version; + } + + // Generates artifact file name from the specified fields. + private String artifactFile(String[] fields) { + return fields.length < 5 ? + artifactFile(fields[1], fields[2], + (fields.length < 4 ? JAR : fields[3]), null) : + artifactFile(fields[1], fields[2], fields[3], fields[4]); + } + + // Generates artifact file name from the specified elements. + private String artifactFile(String aid, String version, String type, + String classifier) { + return classifier == null ? aid + "-" + version + "." + type : + aid + "-" + version + "-" + classifier + "." + type; + } + + // Returns the given string with project variable substitutions. + private String eval(String string) { + return string == null ? null : + string.replaceAll("\\$\\{onos.app.name\\}", name) + .replaceAll("\\$\\{onos.app.origin\\}", origin) + .replaceAll("\\$\\{project.groupId\\}", projectGroupId) + .replaceAll("\\$\\{project.artifactId\\}", projectArtifactId) + .replaceAll("\\$\\{project.version\\}", projectVersion) + .replaceAll("\\$\\{project.description\\}", projectDescription); + } + + // Recursively archives the specified directory into a given ZIP stream. + private void zipDirectory(String root, File dir, ZipOutputStream zos) + throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + File[] files = dir.listFiles(); + if (files != null && files.length > 0) { + for (File file : files) { + if (file.isDirectory()) { + String path = root + file.getName() + "/"; + zos.putNextEntry(new ZipEntry(path)); + zipDirectory(path, file, zos); + zos.closeEntry(); + } else { + FileInputStream fin = new FileInputStream(file); + zos.putNextEntry(new ZipEntry(root + file.getName())); + int length; + while ((length = fin.read(buffer)) > 0) { + zos.write(buffer, 0, length); + } + zos.closeEntry(); + fin.close(); + } + } + } + } +} diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java new file mode 100644 index 00000000..3e3e17a0 --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosCfgMojo.java @@ -0,0 +1,141 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * 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. + */ +package org.onosproject.maven; + +import com.thoughtworks.qdox.JavaProjectBuilder; +import com.thoughtworks.qdox.model.JavaAnnotation; +import com.thoughtworks.qdox.model.JavaClass; +import com.thoughtworks.qdox.model.JavaField; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * Produces ONOS component configuration catalogue resources. + */ +@Mojo(name = "cfg", defaultPhase = LifecyclePhase.GENERATE_RESOURCES) +public class OnosCfgMojo extends AbstractMojo { + + private static final String COMPONENT = "org.apache.felix.scr.annotations.Component"; + private static final String PROPERTY = "org.apache.felix.scr.annotations.Property"; + private static final String SEP = "|"; + + /** + * The directory where the generated catalogue file will be put. + */ + @Parameter(defaultValue = "${basedir}") + protected File srcDirectory; + + /** + * The directory where the generated catalogue file will be put. + */ + @Parameter(defaultValue = "${project.build.outputDirectory}") + protected File dstDirectory; + + @Override + public void execute() throws MojoExecutionException { + getLog().info("Generating ONOS component configuration catalogues..."); + try { + JavaProjectBuilder builder = new JavaProjectBuilder(); + builder.addSourceTree(new File(srcDirectory, "src/main/java")); + builder.getClasses().forEach(this::processClass); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private void processClass(JavaClass javaClass) { + boolean isComponent = javaClass.getAnnotations().stream() + .map(ja -> ja.getType().getName().equals(COMPONENT)) + .findFirst().isPresent(); + if (isComponent) { + List<String> lines = new ArrayList<>(); + javaClass.getFields().forEach(field -> processField(lines, javaClass, field)); + if (!lines.isEmpty()) { + writeCatalog(javaClass, lines); + } + } + } + + private void writeCatalog(JavaClass javaClass, List<String> lines) { + File dir = new File(dstDirectory, javaClass.getPackageName().replace('.', '/')); + dir.mkdirs(); + + File cfgDef = new File(dir, javaClass.getName().replace('.', '/') + ".cfgdef"); + try (FileWriter fw = new FileWriter(cfgDef); + PrintWriter pw = new PrintWriter(fw)) { + pw.println("# This file is auto-generated by onos-maven-plugin"); + lines.forEach(pw::println); + } catch (IOException e) { + System.err.println("Unable to write catalog for " + javaClass.getName()); + e.printStackTrace(); + } + } + + private void processField(List<String> lines, JavaClass javaClass, JavaField field) { + field.getAnnotations().forEach(ja -> { + if (ja.getType().getName().equals(PROPERTY)) { + lines.add(expand(javaClass, ja.getNamedParameter("name").toString()) + + SEP + type(field) + + SEP + defaultValue(javaClass, field, ja) + + SEP + description(ja)); + } + }); + } + + // TODO: Stuff below is very much hack-ish and should be redone; it works for now though. + + private String description(JavaAnnotation annotation) { + String description = (String) annotation.getNamedParameter("label"); + return description.replaceAll("\" \\+ \"", "") + .replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", ""); + } + + private String type(JavaField field) { + String ft = field.getType().getName().toUpperCase(); + return ft.equals("INT") ? "INTEGER" : ft; + } + + private String defaultValue(JavaClass javaClass, JavaField field, + JavaAnnotation annotation) { + String ft = field.getType().getName().toLowerCase(); + String defValueName = ft.equals("boolean") ? "boolValue" : + ft.equals("string") ? "value" : ft + "Value"; + Object dv = annotation.getNamedParameter(defValueName); + return dv == null ? "" : expand(javaClass, dv.toString()); + } + + private String stripQuotes(String string) { + return string.trim().replaceFirst("^[^\"]*\"", "").replaceFirst("\"$", ""); + } + + private String expand(JavaClass javaClass, String value) { + JavaField field = javaClass.getFieldByName(value); + return field == null ? stripQuotes(value) : + stripQuotes(field.getCodeBlock().replaceFirst(".*=", "").replaceFirst(";$", "")); + } + +} diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java new file mode 100644 index 00000000..ea847459 --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/java/org/onosproject/maven/OnosSwaggerMojo.java @@ -0,0 +1,451 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * 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. + */ +package org.onosproject.maven; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.thoughtworks.qdox.JavaProjectBuilder; +import com.thoughtworks.qdox.model.DocletTag; +import com.thoughtworks.qdox.model.JavaAnnotation; +import com.thoughtworks.qdox.model.JavaClass; +import com.thoughtworks.qdox.model.JavaMethod; +import com.thoughtworks.qdox.model.JavaParameter; +import com.thoughtworks.qdox.model.JavaType; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static com.google.common.base.Strings.isNullOrEmpty; + +/** + * Produces ONOS Swagger api-doc. + */ +@Mojo(name = "swagger", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class OnosSwaggerMojo extends AbstractMojo { + private final ObjectMapper mapper = new ObjectMapper(); + + private static final String JSON_FILE = "swagger.json"; + private static final String GEN_SRC = "generated-sources"; + private static final String REG_SRC = "registrator.javat"; + + private static final String PATH = "javax.ws.rs.Path"; + private static final String PATH_PARAM = "javax.ws.rs.PathParam"; + private static final String QUERY_PARAM = "javax.ws.rs.QueryParam"; + private static final String POST = "javax.ws.rs.POST"; + private static final String GET = "javax.ws.rs.GET"; + private static final String PUT = "javax.ws.rs.PUT"; + private static final String DELETE = "javax.ws.rs.DELETE"; + private static final String PRODUCES = "javax.ws.rs.Produces"; + private static final String CONSUMES = "javax.ws.rs.Consumes"; + private static final String JSON = "MediaType.APPLICATION_JSON"; + + /** + * The directory where the generated catalogue file will be put. + */ + @Parameter(defaultValue = "${basedir}") + protected File srcDirectory; + + /** + * The directory where the generated catalogue file will be put. + */ + @Parameter(defaultValue = "${project.build.directory}") + protected File dstDirectory; + + /** + * REST API web-context + */ + @Parameter(defaultValue = "${web.context}") + protected String webContext; + + /** + * REST API version + */ + @Parameter(defaultValue = "${api.version}") + protected String apiVersion; + + /** + * REST API description + */ + @Parameter(defaultValue = "${api.description}") + protected String apiDescription; + + /** + * REST API title + */ + @Parameter(defaultValue = "${api.title}") + protected String apiTitle; + + /** + * REST API title + */ + @Parameter(defaultValue = "${api.package}") + protected String apiPackage; + + /** + * Maven project + */ + @Parameter(defaultValue = "${project}") + protected MavenProject project; + + + @Override + public void execute() throws MojoExecutionException { + try { + JavaProjectBuilder builder = new JavaProjectBuilder(); + builder.addSourceTree(new File(srcDirectory, "src/main/java")); + + ObjectNode root = initializeRoot(); + ArrayNode tags = mapper.createArrayNode(); + ObjectNode paths = mapper.createObjectNode(); + + root.set("tags", tags); + root.set("paths", paths); + + builder.getClasses().forEach(jc -> processClass(jc, paths, tags)); + + if (paths.size() > 0) { + getLog().info("Generating ONOS REST API documentation..."); + genCatalog(root); + + if (!isNullOrEmpty(apiPackage)) { + genRegistrator(); + } + } + + project.addCompileSourceRoot(new File(dstDirectory, GEN_SRC).getPath()); + + } catch (Exception e) { + getLog().warn("Unable to generate ONOS REST API documentation", e); + throw e; + } + } + + // initializes top level root with Swagger required specifications + private ObjectNode initializeRoot() { + ObjectNode root = mapper.createObjectNode(); + root.put("swagger", "2.0"); + ObjectNode info = mapper.createObjectNode(); + root.set("info", info); + + root.put("basePath", webContext); + info.put("version", apiVersion); + info.put("title", apiTitle); + info.put("description", apiDescription); + + ArrayNode produces = mapper.createArrayNode(); + produces.add("application/json"); + root.set("produces", produces); + + ArrayNode consumes = mapper.createArrayNode(); + consumes.add("application/json"); + root.set("consumes", consumes); + + return root; + } + + // Checks whether javaClass has a path tag associated with it and if it does + // processes its methods and creates a tag for the class on the root + void processClass(JavaClass javaClass, ObjectNode paths, ArrayNode tags) { + // If the class does not have a Path tag then ignore it + JavaAnnotation annotation = getPathAnnotation(javaClass); + if (annotation == null) { + return; + } + + String path = getPath(annotation); + if (path == null) { + return; + } + + String resourcePath = "/" + path; + String tagPath = path.isEmpty() ? "/" : path; + + // Create tag node for this class. + ObjectNode tagObject = mapper.createObjectNode(); + tagObject.put("name", tagPath); + if (javaClass.getComment() != null) { + tagObject.put("description", shortText(javaClass.getComment())); + } + tags.add(tagObject); + + // Create an array node add to all methods from this class. + ArrayNode tagArray = mapper.createArrayNode(); + tagArray.add(tagPath); + + processAllMethods(javaClass, resourcePath, paths, tagArray); + } + + private JavaAnnotation getPathAnnotation(JavaClass javaClass) { + Optional<JavaAnnotation> optional = javaClass.getAnnotations() + .stream().filter(a -> a.getType().getName().equals(PATH)).findAny(); + return optional.isPresent() ? optional.get() : null; + } + + // Checks whether a class's methods are REST methods and then places all the + // methods under a specific path into the paths node + private void processAllMethods(JavaClass javaClass, String resourcePath, + ObjectNode paths, ArrayNode tagArray) { + // map of the path to its methods represented by an ObjectNode + Map<String, ObjectNode> pathMap = new HashMap<>(); + + javaClass.getMethods().forEach(javaMethod -> { + javaMethod.getAnnotations().forEach(annotation -> { + String name = annotation.getType().getName(); + if (name.equals(POST) || name.equals(GET) || name.equals(DELETE) || name.equals(PUT)) { + // substring(12) removes "javax.ws.rs." + String method = annotation.getType().toString().substring(12).toLowerCase(); + processRestMethod(javaMethod, method, pathMap, resourcePath, tagArray); + } + }); + }); + + // for each path add its methods to the path node + for (Map.Entry<String, ObjectNode> entry : pathMap.entrySet()) { + paths.set(entry.getKey(), entry.getValue()); + } + + + } + + private void processRestMethod(JavaMethod javaMethod, String method, + Map<String, ObjectNode> pathMap, + String resourcePath, ArrayNode tagArray) { + String fullPath = resourcePath, consumes = "", produces = "", + comment = javaMethod.getComment(); + for (JavaAnnotation annotation : javaMethod.getAnnotations()) { + String name = annotation.getType().getName(); + if (name.equals(PATH)) { + fullPath = resourcePath + "/" + getPath(annotation); + fullPath = fullPath.replaceFirst("^//", "/"); + } + if (name.equals(CONSUMES)) { + consumes = getIOType(annotation); + } + if (name.equals(PRODUCES)) { + produces = getIOType(annotation); + } + } + ObjectNode methodNode = mapper.createObjectNode(); + methodNode.set("tags", tagArray); + + addSummaryDescriptions(methodNode, comment); + processParameters(javaMethod, methodNode); + + processConsumesProduces(methodNode, "consumes", consumes); + processConsumesProduces(methodNode, "produces", produces); + + addResponses(methodNode); + + ObjectNode operations = pathMap.get(fullPath); + if (operations == null) { + operations = mapper.createObjectNode(); + operations.set(method, methodNode); + pathMap.put(fullPath, operations); + } else { + operations.set(method, methodNode); + } + } + + private void processConsumesProduces(ObjectNode methodNode, String type, String io) { + if (!io.equals("")) { + ArrayNode array = mapper.createArrayNode(); + methodNode.set(type, array); + array.add(io); + } + } + + private void addSummaryDescriptions(ObjectNode methodNode, String comment) { + String summary = "", description; + if (comment != null) { + if (comment.contains(".")) { + int periodIndex = comment.indexOf("."); + summary = comment.substring(0, periodIndex); + description = comment.length() > periodIndex + 1 ? + comment.substring(periodIndex + 1).trim() : ""; + } else { + description = comment; + } + methodNode.put("summary", summary); + methodNode.put("description", description); + } + } + + // Temporary solution to add responses to a method + // TODO Provide annotations in the web resources for responses and parse them + private void addResponses(ObjectNode methodNode) { + ObjectNode responses = mapper.createObjectNode(); + methodNode.set("responses", responses); + + ObjectNode success = mapper.createObjectNode(); + success.put("description", "successful operation"); + responses.set("200", success); + + ObjectNode defaultObj = mapper.createObjectNode(); + defaultObj.put("description", "Unexpected error"); + responses.set("default", defaultObj); + } + + // Checks if the annotations has a value of JSON and returns the string + // that Swagger requires + private String getIOType(JavaAnnotation annotation) { + if (annotation.getNamedParameter("value").toString().equals(JSON)) { + return "application/json"; + } + return ""; + } + + // If the annotation has a Path tag, returns the value with leading and + // trailing double quotes and slash removed. + private String getPath(JavaAnnotation annotation) { + String path = annotation.getNamedParameter("value").toString(); + return path == null ? null : path.replaceAll("(^[\\\"/]*|[/\\\"]*$)", ""); + } + + // Processes parameters of javaMethod and enters the proper key-values into the methodNode + private void processParameters(JavaMethod javaMethod, ObjectNode methodNode) { + ArrayNode parameters = mapper.createArrayNode(); + methodNode.set("parameters", parameters); + boolean required = true; + + for (JavaParameter javaParameter : javaMethod.getParameters()) { + ObjectNode individualParameterNode = mapper.createObjectNode(); + Optional<JavaAnnotation> optional = javaParameter.getAnnotations().stream().filter( + annotation -> annotation.getType().getName().equals(PATH_PARAM) || + annotation.getType().getName().equals(QUERY_PARAM)).findAny(); + JavaAnnotation pathType = optional.isPresent() ? optional.get() : null; + + String annotationName = javaParameter.getName(); + + + if (pathType != null) { //the parameter is a path or query parameter + individualParameterNode.put("name", + pathType.getNamedParameter("value").toString().replace("\"", "")); + if (pathType.getType().getName().equals(PATH_PARAM)) { + individualParameterNode.put("in", "path"); + } else if (pathType.getType().getName().equals(QUERY_PARAM)) { + individualParameterNode.put("in", "query"); + } + individualParameterNode.put("type", getType(javaParameter.getType())); + } else { // the parameter is a body parameter + individualParameterNode.put("name", annotationName); + individualParameterNode.put("in", "body"); + + // TODO add actual hardcoded schemas and a type + // body parameters must have a schema associated with them + ArrayNode schema = mapper.createArrayNode(); + individualParameterNode.set("schema", schema); + } + for (DocletTag p : javaMethod.getTagsByName("param")) { + if (p.getValue().contains(annotationName)) { + try { + String description = p.getValue().split(" ", 2)[1].trim(); + if (description.contains("optional")) { + required = false; + } + individualParameterNode.put("description", description); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + individualParameterNode.put("required", required); + parameters.add(individualParameterNode); + } + } + + // Returns the Swagger specified strings for the type of a parameter + private String getType(JavaType javaType) { + String type = javaType.getFullyQualifiedName(); + String value; + if (type.equals(String.class.getName())) { + value = "string"; + } else if (type.equals("int")) { + value = "integer"; + } else if (type.equals(boolean.class.getName())) { + value = "boolean"; + } else if (type.equals(long.class.getName())) { + value = "number"; + } else { + value = ""; + } + return value; + } + + // Writes the swagger.json file using the supplied JSON root. + private void genCatalog(ObjectNode root) { + File swaggerCfg = new File(dstDirectory, JSON_FILE); + if (dstDirectory.exists() || dstDirectory.mkdirs()) { + try (FileWriter fw = new FileWriter(swaggerCfg); + PrintWriter pw = new PrintWriter(fw)) { + pw.println(root.toString()); + } catch (IOException e) { + getLog().warn("Unable to write " + JSON_FILE); + } + } else { + getLog().warn("Unable to create " + dstDirectory); + } + } + + // Generates the registrator Java component. + private void genRegistrator() { + File dir = new File(dstDirectory, GEN_SRC); + File reg = new File(dir, apiPackage.replaceAll("\\.", "/") + "/ApiDocRegistrator.java"); + File pkg = reg.getParentFile(); + if (pkg.exists() || pkg.mkdirs()) { + try { + String src = new String(ByteStreams.toByteArray(getClass().getResourceAsStream(REG_SRC))); + src = src.replace("${api.package}", apiPackage) + .replace("${web.context}", webContext) + .replace("${api.title}", apiTitle) + .replace("${api.description}", apiTitle); + Files.write(src.getBytes(), reg); + } catch (IOException e) { + getLog().warn("Unable to write " + reg); + } + } else { + getLog().warn("Unable to create " + reg); + } + } + + // Returns "nickname" based on method and path for a REST method + private String setNickname(String method, String path) { + if (!path.equals("")) { + return (method + path.replace('/', '_').replace("{", "").replace("}", "")).toLowerCase(); + } else { + return method.toLowerCase(); + } + } + + private String shortText(String comment) { + int i = comment.indexOf('.'); + return i > 0 ? comment.substring(0, i) : comment; + } + +} diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml new file mode 100644 index 00000000..0f3133d3 --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/app.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<app name="${onos.app.name}" origin="${onos.app.origin}" version="${project.version}" + featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" + features="${project.artifactId}"> + <description>${project.description}</description> + <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> +</app> diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/features.xml b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/features.xml new file mode 100644 index 00000000..d5a91e2a --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/features.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> + <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository> + <feature name="${project.artifactId}" version="${project.version}" + description="${project.description}"> + <feature>onos-api</feature> + <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> + </feature> +</features> diff --git a/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/registrator.javat b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/registrator.javat new file mode 100644 index 00000000..a8e26536 --- /dev/null +++ b/framework/src/onos/tools/package/maven-plugin/src/main/resources/org/onosproject/maven/registrator.javat @@ -0,0 +1,31 @@ +/* + * Auto-generated by OnosSwaggerMojo. + * + * Copyright 2015 Open Networking Laboratory + * + * 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. + */ +package ${api.package}; + +import org.apache.felix.scr.annotations.Component; +import org.onosproject.rest.AbstractApiDocRegistrator; +import org.onosproject.rest.ApiDocProvider; + +@Component(immediate = true) +public class ApiDocRegistrator extends AbstractApiDocRegistrator { + public ApiDocRegistrator() { + super(new ApiDocProvider("${web.context}", + "${api.title}", + ApiDocRegistrator.class.getClassLoader())); + } +} diff --git a/framework/src/onos/tools/test/README b/framework/src/onos/tools/test/README new file mode 100644 index 00000000..3d6b1eb7 --- /dev/null +++ b/framework/src/onos/tools/test/README @@ -0,0 +1 @@ +Artifacts for system testing onos. diff --git a/framework/src/onos/tools/test/bin/find-node.sh b/framework/src/onos/tools/test/bin/find-node.sh new file mode 100644 index 00000000..e76a84a6 --- /dev/null +++ b/framework/src/onos/tools/test/bin/find-node.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +validate_number () { + local re="^[0-9]+$" + if [[ ! $1 =~ $re ]] ; then + return 1 + fi + + return 0 +} + +find_node () { + if validate_number $1 ; then + # input is a number, try to find if an OC node is defined + + oc_try="OC$1" + node=${!oc_try} + + if [ -n "$node" ]; then + # node lookup succeeded, return node + echo $node + else + # node lookup failed, return original input + echo $1 + fi + + else + echo $1 + fi + + return 0 +} diff --git a/framework/src/onos/tools/test/bin/flow-tester.py b/framework/src/onos/tools/test/bin/flow-tester.py new file mode 100644 index 00000000..d77a861b --- /dev/null +++ b/framework/src/onos/tools/test/bin/flow-tester.py @@ -0,0 +1,45 @@ +import concurrent.futures +import requests, json +from optparse import OptionParser + +def run(url, request): + data = json.dumps(request) + r = requests.post(url, data) + return r + +def runTasks(flowPerDevice, neighbours, url, servers, doJson, remove): + # We can use a with statement to ensure threads are cleaned up promptly + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: + # Start the load operations and mark each future with its URL + request = { "flowsPerDevice" : flowPerDevice, "neighbours" : neighbours, "remove" : remove } + future_to_url = {executor.submit(run, url % (server), request) for server in servers} + for f in concurrent.futures.as_completed(future_to_url): + try: + response = f.result() + server = response.url.split('//')[1].split(':')[0] + if (doJson): + print (json.dumps({ "server" : server, "elapsed" : response.json()['elapsed'] })) + else: + print ("%s -> %sms" % (server, response.json()['elapsed'])) + except Exception as exc: + print("Execution failed -> %s" % exc) + +if __name__ == "__main__": + parser = OptionParser() + parser.add_option("-u", "--url", dest="url", help="set the url for the request", + default="http://%s:8181/onos/demo/intents/flowTest") + parser.add_option("-f", "--flows", dest="flows", help="Number of flows to install per device", + default=100, type="int") + parser.add_option("-n", "--neighbours", dest="neighs", help="Number of neighbours to communicate to", + default=0, type="int") + parser.add_option("-s", "--servers", dest="servers", help="List of servers to hit", + default=[], action="append") + parser.add_option("-r", "--remove", dest="remove", help="Do not remove flows after installation", + default=True, action="store_false") + parser.add_option("-j", "--json", dest="doJson", help="Print results in json", + default=False, action="store_true") + + (options, args) = parser.parse_args() + if (len(options.servers) == 0): + options.servers.append("localhost") + runTasks(options.flows, options.neighs, options.url, options.servers, options.doJson, options.remove) diff --git a/framework/src/onos/tools/test/bin/ogroup-opts b/framework/src/onos/tools/test/bin/ogroup-opts new file mode 100644 index 00000000..41842bdd --- /dev/null +++ b/framework/src/onos/tools/test/bin/ogroup-opts @@ -0,0 +1,58 @@ +# Options read by onos-group for help message formatting and sanity checks. +GOPTS='install kill patch-vm push-keys uninstall' + +# Tab completion settings for onos-group. +function _ogroup-opts () { + local cur=${COMP_WORDS[COMP_CWORD]} + if [ $COMP_CWORD -eq 1 ]; then + COMPREPLY=( $( compgen -W "${GOPTS} help" -- $cur ) ) + fi +} + +complete -F _ogroup-opts onos-group + + +# Tab completion settings for stc +function _stc-opts () { + local cur=${COMP_WORDS[COMP_CWORD]} + if [ $COMP_CWORD -eq 1 ]; then + COMPREPLY=( $( compgen -W "$(cd $ONOS_ROOT/tools/test/scenarios && ls -1 | sed 's/.xml//g')" -- $cur ) ) + fi +} + +complete -F _stc-opts stc + + +# Tab completion settings for stl +function _stl-opts () { + local cur=${COMP_WORDS[COMP_CWORD]} + if [ $COMP_CWORD -eq 1 ]; then + COMPREPLY=( $( compgen -W "$(cd /tmp/stc && ls -1)" -- $cur ) ) + elif [ $COMP_CWORD -eq 2 ]; then + COMPREPLY=( $( compgen -W "$(cd /tmp/stc/$3 && ls -1)" -- $cur ) ) + fi +} + +complete -F _stl-opts stl + + +# Tab completion settings for cell +function _cell-opts () { + local cur=${COMP_WORDS[COMP_CWORD]} + if [ $COMP_CWORD -eq 1 ]; then + COMPREPLY=( $( compgen -W "$(cd $ONOS_ROOT/tools/test/cells && ls -1)" -- $cur ) ) + fi +} + +complete -F _cell-opts cell + + +# Tab completion settings for onos-create-app. +function _ocapp-opts () { + local cur=${COMP_WORDS[COMP_CWORD]} + if [ $COMP_CWORD -eq 1 ]; then + COMPREPLY=( $( compgen -W "bundle ui cli" -- $cur ) ) + fi +} + +complete -F _ocapp-opts onos-create-app diff --git a/framework/src/onos/tools/test/bin/old.json b/framework/src/onos/tools/test/bin/old.json new file mode 100644 index 00000000..713efbf6 --- /dev/null +++ b/framework/src/onos/tools/test/bin/old.json @@ -0,0 +1,387 @@ +{ + "linkConfig": [ + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", + "params": { + "nodeName1": "SFO-W10", + "nodeName2": "SJC-W10", + "numWaves": 80, + "port1": 50, + "port2": 30 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03", + "params": { + "nodeName1": "SJC-W10", + "nodeName2": "LAX-W10", + "numWaves": 80, + "port1": 50, + "port2": 30 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04", + "params": { + "nodeName1": "LAX-W10", + "nodeName2": "SDG-W10", + "numWaves": 80, + "port1": 50, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05", + "params": { + "nodeName1": "SFO-W10", + "nodeName2": "MSP-M10", + "numWaves": 80, + "port1": 20, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05", + "params": { + "nodeName1": "SJC-W10", + "nodeName2": "MSP-M10", + "numWaves": 80, + "port1": 20, + "port2": 20 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "nodeName1": "LAX-W10", + "nodeName2": "DFW-M10", + "numWaves": 80, + "port1": 20, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:04", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "nodeName1": "SDG-W10", + "nodeName2": "DFW-M10", + "numWaves": 80, + "port1": 20, + "port2": 20 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "nodeName1": "MSP-M10", + "nodeName2": "DFW-M10", + "numWaves": 80, + "port1": 30, + "port2": 40 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07", + "params": { + "nodeName1": "MSP-M10", + "nodeName2": "CHG-N10", + "numWaves": 80, + "port1": 40, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08", + "params": { + "nodeName1": "DFW-M10", + "nodeName2": "IAD-M10", + "numWaves": 80, + "port1": 30, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08", + "params": { + "nodeName1": "CHG-N10", + "nodeName2": "IAD-M10", + "numWaves": 80, + "port1": 20, + "port2": 30 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09", + "params": { + "nodeName1": "CHG-N10", + "nodeName2": "JFK-M10", + "numWaves": 80, + "port1": 30, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", + "params": { + "nodeName1": "IAD-M10", + "nodeName2": "ATL-S10", + "numWaves": 80, + "port1": 20, + "port2": 50 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:09", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", + "params": { + "nodeName1": "JFK-M10", + "nodeName2": "ATL-S10", + "numWaves": 80, + "port1": 20, + "port2": 20 + }, + "type": "wdmLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:01", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01", + "params": { + "bandwidth": 100000, + "nodeName1": "SFO-R10", + "nodeName2": "SFO-W10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:02", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04", + "params": { + "bandwidth": 100000, + "nodeName1": null, + "nodeName2": "SDG-W10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:03", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "bandwidth": 100000, + "nodeName1": "LAX-R10", + "nodeName2": "DFW-M10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:04", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07", + "params": { + "bandwidth": 100000, + "nodeName1": "SDG-R10", + "nodeName2": "CHG-N10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:05", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09", + "params": { + "bandwidth": 100000, + "nodeName1": null, + "nodeName2": "JFK-M10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + }, + { + "allowed": true, + "nodeDpid1": "00:00:ff:ff:ff:ff:00:06", + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A", + "params": { + "bandwidth": 100000, + "nodeName1": null, + "nodeName2": "ATL-S10", + "port1": 2, + "port2": 10 + }, + "type": "pktOptLink" + } + ], + "switchConfig": [ + { + "allowed": true, + "latitude": 37.6, + "longitude": 122.3, + "name": "SFO-W10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:01", + "params": { + "numRegen": 0 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 37.3, + "longitude": 121.9, + "name": "SJC-W10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:02", + "params": { + "numRegen": 0 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 33.9, + "longitude": 118.4, + "name": "LAX-W10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:03", + "params": { + "numRegen": 0 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 32.8, + "longitude": 117.1, + "name": "SDG-W10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:04", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 44.8, + "longitude": 93.1, + "name": "MSP-M10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:05", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 32.8, + "longitude": 97.1, + "name": "DFW-M10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 41.8, + "longitude": 120.1, + "name": "CHG-N10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:07", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 38.8, + "longitude": 77.1, + "name": "IAD-M10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:08", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 40.8, + "longitude": 73.1, + "name": "JFK-M10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:09", + "params": { + "numRegen": 0 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 33.8, + "longitude": 84.1, + "name": "ATL-S10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:0A", + "params": { + "numRegen": 0 + }, + "type": "Roadm" + }, + { + "allowed": true, + "latitude": 32.8, + "longitude": 97.1, + "name": "DFW-M10", + "nodeDpid": "00:00:ff:ff:ff:ff:ff:06", + "params": { + "numRegen": 3 + }, + "type": "Roadm" + } + ] +} diff --git a/framework/src/onos/tools/test/bin/onos b/framework/src/onos/tools/test/bin/onos new file mode 100755 index 00000000..89197db5 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos @@ -0,0 +1,21 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS remote command-line client. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +[ "$1" = "-w" ] && shift && onos-wait-for-start $1 + +[ -n "$1" ] && OCI=$(find_node $1) && shift + +if which client 1>/dev/null 2>&1 && [ -z "$ONOS_USE_SSH" ]; then + # Use Karaf client only if we can and are allowed to + unset KARAF_HOME + client -h $OCI -u karaf "$@" 2>/dev/null +else + # Otherwise use raw ssh; strict checking is off for dev environments only + ssh -p 8101 -o StrictHostKeyChecking=no $OCI "$@" +fi diff --git a/framework/src/onos/tools/test/bin/onos-archetypes-test b/framework/src/onos/tools/test/bin/onos-archetypes-test new file mode 100755 index 00000000..55f40e76 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-archetypes-test @@ -0,0 +1,21 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Builds a set of projects using ONOS archetypes. +# ----------------------------------------------------------------------------- + +set -e + +export AROOT=/tmp/foo +export ARCHETYPE_OPTS="-DarchetypeGroupId=org.onosproject -DarchetypeVersion=1.3.0-SNAPSHOT" + +mkdir -p $AROOT +for an in api bundle cli ui; do + cd $AROOT + rm -fr $AROOT/foo-$an + mvn archetype:generate $ARCHETYPE_OPTS \ + -DarchetypeArtifactId=onos-$an-archetype \ + -DgroupId=org.foo -DartifactId=foo-$an -Dversion=1.0 \ + -Dpackage=org.foo.$an -DinteractiveMode=false + cd $AROOT/foo-$an + mvn clean install +done diff --git a/framework/src/onos/tools/test/bin/onos-batch b/framework/src/onos/tools/test/bin/onos-batch new file mode 100755 index 00000000..67864a22 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-batch @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Executes selected set of ONOS commands using the batch mode. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} + +commands="${2:-summary,intents,flows,hosts}" + +aux=/tmp/onos-batch.$$ +trap "rm -f $aux" EXIT + +echo "$commands" | tr ',' '\n' > $aux +onos $node -b <$aux diff --git a/framework/src/onos/tools/test/bin/onos-check-apps b/framework/src/onos/tools/test/bin/onos-check-apps new file mode 100755 index 00000000..dfd6b4ef --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-apps @@ -0,0 +1,34 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks whether all and only the ONOS apps configured in ONOS_APPS are active. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +aux=/tmp/stc-$$.log +trap "rm -f $aux $aux.1 $aux.2 2>/dev/null" EXIT + +for attempt in {1..3}; do + onos ${1:-$OCI} "onos:apps -s -a" | grep -v /bin/client > $aux + cat $aux + + # Normalize the installed apps + cut -c7- $aux | grep -v '/bin/client' | cut -d\ -f1 | sort > $aux.1 + + # Normalize the expected apps + apps=${2:-$ONOS_APPS} + apps=${apps:-drivers,openflow} + (for app in ${apps//,/ }; do echo org.onosproject.$app; done) | sort > $aux.2 + + # Check for differences + case ${3:-equals} in + equals) diff $aux.1 $aux.2;; + includes) [ $(egrep -c -f $aux.2 $aux.1) -eq $(wc -l $aux.2 | sed "s|$aux.2||g") ];; + excludes) ! egrep -f $aux.2 $aux.1;; + esac + + [ $? -eq 0 ] && exit 0 || sleep 1 +done + +exit 1; diff --git a/framework/src/onos/tools/test/bin/onos-check-bits b/framework/src/onos/tools/test/bin/onos-check-bits new file mode 100755 index 00000000..0423c342 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-bits @@ -0,0 +1,9 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks if ONOS bits are available in preparation for install. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +ls -l $ONOS_TAR && cksum $ONOS_TAR diff --git a/framework/src/onos/tools/test/bin/onos-check-components b/framework/src/onos/tools/test/bin/onos-check-components new file mode 100755 index 00000000..f4c2df2c --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-components @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks whether all ONOS components are either ACTIVE or DISABLED. +# ----------------------------------------------------------------------------- + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT + +onos ${1:-$OCI} scr:list > $aux +cat $aux +grep -q UNSATISFIED $aux && exit 1 + +if [ -n "$2" ]; then + echo "Searching for ACTIVE $2" + egrep "ACTIVE.*$2" $aux || exit 1 +fi +exit 0
\ No newline at end of file diff --git a/framework/src/onos/tools/test/bin/onos-check-flows b/framework/src/onos/tools/test/bin/onos-check-flows new file mode 100755 index 00000000..6debebcd --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-flows @@ -0,0 +1,15 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks ONOS summary data +# ----------------------------------------------------------------------------- + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT + +onos ${1:-$OCI} "onos:flows" > $aux +cat $aux + +let status=0 +grep "PENDING_" $aux && let status=status+1 + +exit $status
\ No newline at end of file diff --git a/framework/src/onos/tools/test/bin/onos-check-intent b/framework/src/onos/tools/test/bin/onos-check-intent new file mode 100755 index 00000000..e332dc5b --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-intent @@ -0,0 +1,24 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks that all intents in the system have a given state. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT +target=${1:-$OCI} + +echo onos-check-intent: $* + +set -x +for i in {1..10}; do + onos $target "onos:intents" | tee $aux + ( cat $aux | grep "key=$2" | grep "state=$3" ) && cat $aux && exit 0 + sleep 1 +done + +cat $aux +exit 1 + diff --git a/framework/src/onos/tools/test/bin/onos-check-logs b/framework/src/onos/tools/test/bin/onos-check-logs new file mode 100755 index 00000000..ec1013ab --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-logs @@ -0,0 +1,60 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks the logs of the remote ONOS instance and makes sure they are clean. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +remote=$ONOS_USER@${1:-$OCI} + +LOG=$ONOS_INSTALL_DIR/log/karaf.log* + +aux=/tmp/log.$$ + +if [ "$2" = "old" ]; then + ssh $remote "egrep 'ERROR|Exception|Error' $LOG" + +else + ssh $remote " + tac $LOG | awk ' + BEGIN { off = 0; fail = 0; } + / org.apache.karaf.main.lock.SimpleFileLock lock/ { + off = 1; + exit fail; + } + + / ERROR / { + if (!off) { + print \$0; + exc = 0; + fail = 1; + } + } + / WARN / { + if (!off && exc) { + print \$0; + exc = 0; + } + } + + /^[a-zA-Z0-9.]*(Exception|Error)/ { + if (!off) { + print \$0; + exc = 1; + fail = 1; + } + } + + / at / { + if (!off) { + print \$0; + } + } + END { exit fail; } + ' > $aux + status=\$? + tac $aux && rm $aux + exit \$status + " +fi diff --git a/framework/src/onos/tools/test/bin/onos-check-nodes b/framework/src/onos/tools/test/bin/onos-check-nodes new file mode 100755 index 00000000..69187b6a --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-nodes @@ -0,0 +1,20 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks whether all and only the ONOS instances configured active. +# ----------------------------------------------------------------------------- + +aux=/tmp/stc-$$.log +trap "rm -f $aux $aux.1 $aux.2 2>/dev/null" EXIT + +onos ${1:-$OCI} "onos:nodes" | grep -v /bin/client > $aux +cat $aux + +# Normalize the nodes +cut -d= -f3 $aux | cut -d: -f1 | sort > $aux.1 + +# Normalize the expected nodes +nodes=${2:-$ONOS_INSTANCES} +(for node in $nodes; do echo $node; done) | sort > $aux.2 + +# Check for differences +diff $aux.1 $aux.2 diff --git a/framework/src/onos/tools/test/bin/onos-check-summary b/framework/src/onos/tools/test/bin/onos-check-summary new file mode 100755 index 00000000..ab7c22dd --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-summary @@ -0,0 +1,20 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks ONOS summary data +# ----------------------------------------------------------------------------- + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT + +onos ${1:-$OCI} "onos:summary" > $aux +cat $aux + +let status=0 +grep -q "nodes=${2:-.*}" $aux || let status=status+1 +grep -q "devices=${3:-.*}" $aux || let status=status+1 +grep -q "links=${4:-.*}" $aux || let status=status+1 +grep -q "hosts=${5:-.*}" $aux || let status=status+1 +grep -q "flows=${6:-.*}" $aux || let status=status+1 +grep -q "intents=${7:-.*}" $aux || let status=status+1 + +exit $status
\ No newline at end of file diff --git a/framework/src/onos/tools/test/bin/onos-check-views b/framework/src/onos/tools/test/bin/onos-check-views new file mode 100755 index 00000000..421de907 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-check-views @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Checks whether all and only the ONOS apps configured in ONOS_APPS are active. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT + +onos ${1:-$OCI} "onos:ui-views" > $aux +cat $aux + +[ $# -gt 0 ] && shift + +grep "${@:-topo}" $aux
\ No newline at end of file diff --git a/framework/src/onos/tools/test/bin/onos-config b/framework/src/onos/tools/test/bin/onos-config new file mode 100755 index 00000000..5c3ab024 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-config @@ -0,0 +1,57 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely configures & starts ONOS for the first time. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} +remote=$ONOS_USER@$node + +# ONOS boot features +export ONOS_BOOT_FEATURES="${ONOS_BOOT_FEATURES:-webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui}" + +# ONOS builtin apps and providers ignited by default +export ONOS_APPS="${ONOS_APPS:-drivers,openflow}" + +# Generate a cluster.json from the ON* environment variables +CDEF_FILE=/tmp/${remote}.cluster.json +echo "{ \"ipPrefix\": \"$ONOS_NIC\"," > $CDEF_FILE +echo " \"nodes\":[" >> $CDEF_FILE +for node in $(env | sort | egrep "OC[2-9]+" | cut -d= -f2); do + echo " { \"id\": \"$node\", \"ip\": \"$node\", \"tcpPort\": 9876 }," >> $CDEF_FILE +done +echo " { \"id\": \"$OC1\", \"ip\": \"$OC1\", \"tcpPort\": 9876 }" >> $CDEF_FILE +echo "]}" >> $CDEF_FILE +scp -q $CDEF_FILE $remote:$ONOS_INSTALL_DIR/config/cluster.json + +ssh $remote " + echo \"onos.ip = \$(sudo ifconfig | grep $ONOS_NIC | cut -d: -f2 | cut -d\\ -f1)\" \ + >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/system.properties + + # Drop copycat related log level for the console + echo "log4j.logger.net.kuujo.copycat= INFO" \ + >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.ops4j.pax.logging.cfg + + # Patch the Apache Karaf distribution file to load ONOS boot features + perl -pi.old -e \"s|^(featuresBoot=.*,management)(,webconsole,.*)|\1,$ONOS_BOOT_FEATURES|\" \ + $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.apache.karaf.features.cfg + + # Customize which builtin apps should be ignited + for app in $(echo $ONOS_APPS | tr ',' ' '); do + touch $ONOS_INSTALL_DIR/apps/org.onosproject.\$app/active + done +" + +# Generate a default tablets.json from the ON* environment variables +TDEF_FILE=/tmp/${remote}.tablets.json +onos-gen-partitions $TDEF_FILE +scp -q $TDEF_FILE $remote:$ONOS_INSTALL_DIR/config/tablets.json + +# Copy tools/package/config/ to remote +scp -qr ${ONOS_ROOT}/tools/package/config/ $remote:$ONOS_INSTALL_DIR/ + +# Copy the desired initial network configuration to remote if needed +[ -n "$ONOS_CFG" -a -f "$ONOS_CFG" -a "${1:-$OCI}" = "$OC1" ] && \ + scp $ONOS_CFG $remote:$ONOS_INSTALL_DIR/config/network-cfg.json diff --git a/framework/src/onos/tools/test/bin/onos-create-intent b/framework/src/onos/tools/test/bin/onos-create-intent new file mode 100755 index 00000000..d1c0b93d --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-create-intent @@ -0,0 +1,22 @@ +#!/bin/bash +#! usage: onos-create-intent target-onos-instance name point deviceId1 deviceId2 +#! onos-create-intent target-onos-instance name host hostId1 hostId2 +# ----------------------------------------------------------------------------- +# Installs a new intent using the ONOS CLI +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +aux=/tmp/stc-$$.log +trap "rm -f $aux 2>/dev/null" EXIT +target=$1 +name=$2 +type=$3 +arg1=$4 +arg2=$5 + +set -x + +onos $target "onos:add-${type}-intent" --key $name "${arg1}" "${arg2}" + diff --git a/framework/src/onos/tools/test/bin/onos-die b/framework/src/onos/tools/test/bin/onos-die new file mode 100755 index 00000000..9da768e8 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-die @@ -0,0 +1,9 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely kills and stops the ONOS service on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +onos-kill "${1:-$OCI}" && onos-service "${1:-$OCI}" stop diff --git a/framework/src/onos/tools/test/bin/onos-fetch-logs b/framework/src/onos/tools/test/bin/onos-fetch-logs new file mode 100755 index 00000000..a4d7ffee --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-fetch-logs @@ -0,0 +1,43 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Collect ONOS logs from a single node or the current ONOS cell. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +function print_usage { + command_name=`basename $0` + echo "Collect ONOS logs from a single node or the current ONOS cell." + echo + echo "Usage: $command_name <TARGET> " + echo " $command_name [-h | --help]" + echo "Options:" + echo " TARGET The target of the command" + echo " [-h | --help] Print this help" + echo "" + echo "TARGET: <hostname | --cell>" + echo " hostname Execute on the specified host name" + echo " --cell Execute on the current ONOS cell" + echo "" +} + +# Print usage +if [ "${1}" = "-h" -o "${1}" = "--help" ]; then + print_usage + exit 0 +fi + +# Select the target +if [ "${1}" = "--cell" ]; then + nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) +else + nodes=${1:-$OCI} +fi + +# Execute the remote commands +for node in $nodes; do + echo "fetching from ${node}..." + mkdir -p ${node} + scp -p $ONOS_USER@${node}:$ONOS_INSTALL_DIR/log/karaf.log* ./${node}/ +done diff --git a/framework/src/onos/tools/test/bin/onos-fetch-vms b/framework/src/onos/tools/test/bin/onos-fetch-vms new file mode 100755 index 00000000..567f7f5b --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-fetch-vms @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely fetches the ONOS test VMs from a local share into ~/Downloads. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +mkdir -p /tmp/onos +mount -t smbfs smb://guest:@10.254.1.15/onos /tmp/onos +cp /tmp/onos/onos*.ova ~/Downloads diff --git a/framework/src/onos/tools/test/bin/onos-form-cluster b/framework/src/onos/tools/test/bin/onos-form-cluster new file mode 100755 index 00000000..daca34cc --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-form-cluster @@ -0,0 +1,32 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Forms ONOS cluster using REST API. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +# Scan arguments for user/password or other options... +while getopts u:p: o; do + case "$o" in + u) user=$OPTARG;; + p) password=$OPTARG;; + esac +done +user=${user:-onos} # user defaults to 'onos' +password=${password:-$user} # password defaults to user name if not specified +let OPC=$OPTIND-1 +shift $OPC + +node=${1:-$OCI} + +if [ $node = "cell" ]; then + nodes=${ONOS_INSTANCES} + node=${OCI} +else + nodes="$@" +fi + +set -x + +ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-form-cluster -u $user -p $password $nodes diff --git a/framework/src/onos/tools/test/bin/onos-gen-partitions b/framework/src/onos/tools/test/bin/onos-gen-partitions new file mode 100755 index 00000000..a2558392 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-gen-partitions @@ -0,0 +1,52 @@ +#!/usr/bin/env python +''' + Generate the partitions json file from the $OC* environment variables + + Usage: onos-gen-partitions [output file] + If output file is not provided, the json is written to stdout. +''' + +from os import environ +from collections import deque, OrderedDict +import re +import json +import sys + +convert = lambda text: int(text) if text.isdigit() else text.lower() +alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] + +def get_OC_vars(): + vars = [] + for var in environ: + if re.match(r"OC[0-9]+", var): + vars.append(var) + return sorted(vars, key=alphanum_key) + +def get_nodes(vars, port=9876): + node = lambda k: { 'id': k, 'ip': k, 'tcpPort': port } + return [ node(environ[v]) for v in vars ] + +def generate_permutations(nodes, k): + l = deque(nodes) + perms = {} + for i in range(1, len(nodes)+1): + perms['p%d' % i] = list(l)[:k] + l.rotate(-1) + return OrderedDict(sorted(perms.iteritems(), key=lambda (k, v): alphanum_key(k))) + +if __name__ == '__main__': + vars = get_OC_vars() + nodes = get_nodes(vars) + partitions = generate_permutations(nodes, 3) + data = { + 'nodes': nodes, + 'partitions': partitions + } + output = json.dumps(data, indent=4) + + if len(sys.argv) == 2: + filename = sys.argv[1] + with open(filename, 'w') as f: + f.write(output) + else: + print output diff --git a/framework/src/onos/tools/test/bin/onos-group b/framework/src/onos/tools/test/bin/onos-group new file mode 100755 index 00000000..150f9470 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-group @@ -0,0 +1,90 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Allows a select group of commands to be sent to all ONOS instances in a cell. +# ----------------------------------------------------------------------------- + +set -o pipefail +IFS=$'\n' + +source ogroup-opts + +function err() { + printf '%s: %s: %s\n' "$(basename $0)" "$1" "$2" >&2 + usage >&2 + exit 1 +} + +function usage() { +cat << EOF + +usage: $(basename $0) <help|[command]> + +Sends a command to all ONOS instances in the current cell. Currently supported +commands are: $GOPTS + +options: + [command] : A command to send to the instances. + help : Displays this message and exits. + +notes: + Hitting <TAB> will display the options for $(basename $0). + +EOF +} + +# gets the utility name +function getcmd() { + # check that utility can be run in "batch-mode" + local isgopt=false + for c in $(printf '%s' "$GOPTS" | tr ' ' $'\n'); do + [ "$c" = "$1" ] && isgopt=true && break + done + if $isgopt ; then + printf 'onos-%s' "$1" + else + err 'unsupported command' "$1" + fi +} + +# early sanity check for instances/arguments +[ -z "$1" ] && usage && exit 0 + +OCIS=( $(env | sed -ne 's:OC[0-9]\{1,\}=\(.*\):\1 :g p' | sort -k1) ) +if [ -z "$OCIS" ]; then + printf "no controller instances, quitting early" >&2 && exit 0 +fi + +CMD_HELP=false +while [ $# -gt 0 ]; do + case "$1" in + 'help') + usage && exit 0 + ;; + '-'?) + err 'invalid flag' "$1" && exit 1 + ;; + *) + cmd=$(getcmd $1) || exit 1 + shift + # grab flags aimed at the utility being called. + argv=( $@ ) + args=() + for i in "${!argv[@]}"; do + # 'help' is a parameter for us; '-h' is for the command + [ "${argv[$i]}" = 'help' ] && break + [ "${argv[$i]}" = '-h' ] && CMD_HELP=true + args[$i]="${argv[$i]}" + shift + done + continue + ;; + esac + shift +done + +( $CMD_HELP ) && $cmd '-h' && exit 0 + +# TODO: verbose-mode and cleanup +for i in ${OCIS[@]}; do + ${cmd} $(echo ${args[@]}) "$i" 2>/dev/null & +done diff --git a/framework/src/onos/tools/test/bin/onos-gui b/framework/src/onos/tools/test/bin/onos-gui new file mode 100755 index 00000000..517ed11b --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-gui @@ -0,0 +1,9 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Launches ONOS GUI on the specified node. +# ----------------------------------------------------------------------------- + +host=${1:-$OCI} +host=${host:-localhost} + +open http://$host:8181/onos/ui diff --git a/framework/src/onos/tools/test/bin/onos-install b/framework/src/onos/tools/test/bin/onos-install new file mode 100755 index 00000000..0f4cc9dd --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-install @@ -0,0 +1,67 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely pushes bits to a remote node and installs ONOS on it. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +while getopts fnm: o; do + case "$o" in + f) uninstall=true;; + n) nostart=true;; + m) mvn_settings=$OPTARG;; + esac +done +let OPC=$OPTIND-1 +shift $OPC + +# If the -f was given, attempt uninstall first. +[ -n "$uninstall" ] && onos-uninstall ${1:-$OCI} + +node=${1:-$OCI} +remote=$ONOS_USER@$node + +$(dirname $0)/onos-push-bits $node + +[ ! -z "$mvn_settings" ] && scp -q $mvn_settings $remote:/tmp/settings.xml + +ssh $remote " + [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1 + + # Prepare a landing zone and unroll the bits + sudo mkdir -p $ONOS_INSTALL_DIR && sudo chown ${ONOS_USER}:${ONOS_GROUP} $ONOS_INSTALL_DIR + tar zxmf /tmp/$ONOS_BITS.tar.gz -C $ONOS_INSTALL_DIR --strip-components=1 + + # Make a link to the log file directory and make a home for auxiliaries + ln -s $ONOS_INSTALL_DIR/$KARAF_DIST/data/log /opt/onos/log + mkdir $ONOS_INSTALL_DIR/var + mkdir $ONOS_INSTALL_DIR/config + + # create dir for Raft log + # TODO: use $KARAF_DATA + mkdir -p -- $ONOS_INSTALL_DIR/$KARAF_DIST/data/raft + + # Install the upstart configuration file and setup options for debugging + [ -z "$nostart" ] && sudo cp $ONOS_INSTALL_DIR/debian/onos.conf /etc/init/onos.conf + echo 'export ONOS_OPTS=debug' > $ONOS_INSTALL_DIR/options + + # Setup correct user to run onos-service + echo 'export ONOS_USER="${ONOS_USER:-sdn}"' >> $ONOS_INSTALL_DIR/options + + # Remove any previous ON.Lab bits from ~/.m2 repo. + rm -fr ~/.m2/repository/org/onosproject + + [ ! -z "$mvn_settings" ] && cp /tmp/settings.xml ~/.m2/settings.xml + + # Drop log level for the console + echo "log4j.logger.org.apache.sshd = WARN" \ + >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.ops4j.pax.logging.cfg + +" + +# Configure the ONOS installation +onos-config $node + +# Unless -n option was given, attempt to ignite the ONOS service. +[ -z "$nostart" ] && onos-service $node start diff --git a/framework/src/onos/tools/test/bin/onos-intentperf-scrape b/framework/src/onos/tools/test/bin/onos-intentperf-scrape new file mode 100755 index 00000000..8d698b1a --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-intentperf-scrape @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Scrapes intent performance numbers from the remote ONOS log file. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + +for node in $nodes; do + echo "fetching from ${node}..." + ssh $ONOS_USER@${node} " + grep 'Throughput: OVERALL=' $ONOS_INSTALL_DIR/log/karaf.log \ + | sed 's/ | INFO .*\: OVERALL=/|/;s/\; INSTALL_REQ=.*//;s/\; CURRENT=/|/' | cut -c12- + " > ${node}.perf.log +done diff --git a/framework/src/onos/tools/test/bin/onos-iterm-cli b/framework/src/onos/tools/test/bin/onos-iterm-cli new file mode 100755 index 00000000..85cee831 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-iterm-cli @@ -0,0 +1,42 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# Test utility to spawn an iTerm window for testing against current cell. +#------------------------------------------------------------------------------- + +cellName=$ONOS_CELL +nodeCount=$(env | egrep "OC[0-9]+" | wc -l | tr -d ' ') + +osascript -e " +tell application \"iTerm\" + + set cellName to \"$cellName\" + set paneCount to $nodeCount + + set theTerm to (make new terminal) + + tell theTerm + set number of columns to 292 + set number of rows to 24 + launch session \"Default\" + tell the current session + set name to \"ONOS Shell 1\" + write text \"cell \" & cellName + write text \"oi 1 && clear && echo Node \$OCI\" + end tell + end tell + + tell theTerm + repeat with thePane from 2 to paneCount + tell the current session + tell application \"System Events\" to keystroke \"d\" using command down + set name to \"ONOS Shell \" & thePane + write text \"cell \" & cellName + write text \"oi \" & thePane & \" && clear && echo Node \$OCI\" + end tell + end repeat + end tell + + tell application \"System Events\" to keystroke \"I\" using command down + +end tell +" diff --git a/framework/src/onos/tools/test/bin/onos-iterm-logs b/framework/src/onos/tools/test/bin/onos-iterm-logs new file mode 100755 index 00000000..b160c6e0 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-iterm-logs @@ -0,0 +1,42 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# Test utility to spawn an iTerm window for monitoring logs of current cell. +#------------------------------------------------------------------------------- + +cellName=$ONOS_CELL +nodeCount=$(env | egrep "OC[0-9]+" | wc -l | tr -d ' ') + +osascript -e " +tell application \"iTerm\" + + set cellName to \"$cellName\" + set paneCount to $nodeCount + + set theTerm to (make new terminal) + + tell theTerm + set number of columns to 292 + set number of rows to 64 + launch session \"Default\" + tell the current session + set name to \"ONOS Log 1\" + write text \"cell \" & cellName + write text \"oi 1 && clear && echo Node \$OCI && ol\" + end tell + end tell + + tell theTerm + repeat with thePane from 2 to paneCount + tell the current session + tell application \"System Events\" to keystroke \"D\" using command down + set name to \"ONOS Log \" & thePane + write text \"cell \" & cellName + write text \"oi \" & thePane & \" && clear && echo Node \$OCI && ol\" + end tell + end repeat + end tell + + tell application \"System Events\" to keystroke \"I\" using command down + +end tell +" diff --git a/framework/src/onos/tools/test/bin/onos-jpenable b/framework/src/onos/tools/test/bin/onos-jpenable new file mode 100755 index 00000000..ba3492ae --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-jpenable @@ -0,0 +1,19 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely instruments the ONOS JVM for profiling with jprofiler. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +export JPROFILER_ROOT=${JPROFILER_ROOT:-/opt/jprofiler8} + +ssh $ONOS_USER@${1:-$OCI} " + pid=\$(ps -ef | grep karaf.jar | grep -v grep | cut -c10-15 | tr -d ' ') + if [ -n \"\$pid\" ]; then + echo \"Enabling profiling for ONOS process \$pid on \$(hostname)...\" + $JPROFILER_ROOT/bin/jpenable --gui --pid=\$pid --port=8849 + else + echo \"ONOS process is not running...\" + exit 1 + fi +" diff --git a/framework/src/onos/tools/test/bin/onos-kill b/framework/src/onos/tools/test/bin/onos-kill new file mode 100755 index 00000000..47e5360b --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-kill @@ -0,0 +1,18 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely kills the ONOS service on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +ssh $ONOS_USER@${1:-$OCI} " + pid=\$(ps -ef | grep karaf.jar | grep -v grep | cut -c10-15 | tr -d ' ') + if [ -n \"\$pid\" ]; then + echo \"Killing ONOS process \$pid on \$(hostname)...\" + kill -9 \$pid + else + echo \"ONOS process is not running...\" + exit 1 + fi +" diff --git a/framework/src/onos/tools/test/bin/onos-list-cells b/framework/src/onos/tools/test/bin/onos-list-cells new file mode 100755 index 00000000..39a70ee9 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-list-cells @@ -0,0 +1,18 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# List available ONOS cells configuration. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +# Lists available cells +for cell in $(ls -1 $ONOS_ROOT/tools/test/cells); do + if [ ${cell} = "${ONOS_CELL}" ]; then + cell_id="${cell} *" + else + cell_id="${cell}" + fi + cell_descr="$(grep '^#' $ONOS_ROOT/tools/test/cells/$cell | head -n 1)" + printf "%-12s %s\n" "${cell_id}" "${cell_descr}" +done diff --git a/framework/src/onos/tools/test/bin/onos-local b/framework/src/onos/tools/test/bin/onos-local new file mode 100755 index 00000000..acf090c8 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-local @@ -0,0 +1,7 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS local karaf server start. +# ----------------------------------------------------------------------------- + +unset KARAF_HOME +karaf "$@"
\ No newline at end of file diff --git a/framework/src/onos/tools/test/bin/onos-log b/framework/src/onos/tools/test/bin/onos-log new file mode 100755 index 00000000..fe89f6dd --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-log @@ -0,0 +1,38 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Monitors remote ONOS log file on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +less=0 +[ "$1" = "-l" ] && shift && less=1 + +remote=$(find_node $1) + +remote=$ONOS_USER@${remote:-$OCI} +instance=$2 + +pattern=$3 + +[ -n "$instance" -a "$instance" != "-" ] && \ + LOG=$ONOS_INSTALL_DIR/$KARAF_DIST/instances/$instance/data/log/karaf.log || \ + LOG=$ONOS_INSTALL_DIR/log/karaf.log + + +if [ $less -eq 1 ]; then + ssh -t $remote "less $LOG" +elif [ -n "$pattern" ]; then + ssh $remote "grep $LOG -Ee \"$pattern\"" +else + ssh -t $remote " + while true; do + echo ================================================================== + [ ! -f $LOG ] && sleep 2 && continue + [ \$(uname) = "Darwin" ] && tail -n 512 -f -F $LOG || + tail -n 512 --follow=name $LOG --pid \$$ --sleep-interval 2 + done + " +fi diff --git a/framework/src/onos/tools/test/bin/onos-log-kill b/framework/src/onos/tools/test/bin/onos-log-kill new file mode 100755 index 00000000..c18d9231 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-log-kill @@ -0,0 +1,16 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Kills all remote ONOS log file monitors on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +less=0 +[ "$1" = "-l" ] && shift && less=1 + +remote=$(find_node $1) +remote=$ONOS_USER@${remote:-$OCI} + +ssh $remote "ps -ef | grep \"tail -n 512\" | grep -v grep | cut -c10-15 | xargs kill" diff --git a/framework/src/onos/tools/test/bin/onos-log-write b/framework/src/onos/tools/test/bin/onos-log-write new file mode 100755 index 00000000..840c43f5 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-log-write @@ -0,0 +1,37 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Writes block text into the remote ONOS log file on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +remote=$(find_node $1) +remote=$ONOS_USER@${remote:-$OCI} +message=$2 + +if [ -z "$message" ]; then + echo "Usage: onos-log-write <instance> <message>" + exit +fi +if [ -z $(which figlet) ]; then + echo "Install figlet; example: brew install figlet" + exit +fi + +#text=$(figlet $message) +#echo "Writing to $remote:" +#echo $text +#echo + +[ -n "$instance" ] && \ + LOG=$ONOS_INSTALL_DIR/$KARAF_DIST/instances/$instance/data/log/karaf.log || \ + LOG=$ONOS_INSTALL_DIR/log/karaf.log + +#broken by special chars like ` +#ssh -t $remote "sudo mkdir -p $(dirname $LOG) && echo $text | sudo tee -a $LOG" + +figlet $message > /tmp/message.txt +scp /tmp/message.txt $remote:/tmp +ssh -t $remote "sudo mkdir -p $(dirname $LOG) && cat /tmp/message.txt | sudo tee -a $LOG; rm /tmp/message.txt" diff --git a/framework/src/onos/tools/test/bin/onos-mininet b/framework/src/onos/tools/test/bin/onos-mininet new file mode 100755 index 00000000..ef2c8ea5 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-mininet @@ -0,0 +1,69 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts or interacts with mininet in a remote screen session. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +export MAX_WAIT=60 + +cmd="$1" && shift +log="screenlog.0" +remote="$ONOS_USER@$OCN" +mininet="ssh -t -t $remote screen -L -S mininet" + +case $cmd in +send) + $mininet -X "stuff \"$@\\n\"" 2>/dev/null + ;; + +sendAndExpect) + cmd="" + for a in $*; do shift; if [ "$a" = "--expect" ]; then break; fi; cmd="$cmd $a"; done + $mininet -X "stuff \"$cmd\\n\"" 2>/dev/null + onos-mininet expect "$@" + ;; + +wait) + ssh $remote " + let count=0 + sleep 1 && while test ! -f $log; do if test \$count -ge $MAX_WAIT; then exit 1; fi; sleep 1; let count=count+1; done + while ! (tail -n1 $log | egrep -q '^mininet>'); do if [ \$count -ge $MAX_WAIT ]; then exit 1; fi; sleep 1; done + sleep ${1-:1} + " + ;; + +expect) + aux=/tmp/mininet.$$.log + ssh $remote " + sleep 1 + if [ ! -f $log ]; then exit 1; fi; + let count=0 + while ! (tail -n1 $log | egrep -q '^mininet>'); do if test \$count -ge $MAX_WAIT; then exit 1; fi; sleep 1; let count=count+1; done + tac $log | awk '{ print \$0; } /^mininet>/ { if (on) { exit 0; } on=1; }' | tac > $aux + cat $aux + set -x + egrep \"$@\" $aux + " + ;; + +attach) + $mininet -x + ;; + +start) + ssh $remote "rm -f $log; echo logfile flush 1 > ~/.screenrc" + ( + $mininet "$@" + scp $remote:$log /tmp/mininet.log + ssh $remote rm -f $log + ) & + ;; + +stop) + $mininet -X "stuff \"^C\\n\"" 2>/dev/null && \ + $mininet -X "stuff \"^C\\n\"" 2>/dev/null && \ + $mininet -X "stuff \"exit\\n\"" 2>/dev/null + ;; +esac diff --git a/framework/src/onos/tools/test/bin/onos-oecfg b/framework/src/onos/tools/test/bin/onos-oecfg new file mode 100755 index 00000000..e709ce31 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-oecfg @@ -0,0 +1,12 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS OE-Linc config generator. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +APP=onos-app-oecfg +JAR=$M2_REPO/org/onosproject/$APP/$ONOS_POM_VERSION/$APP-$ONOS_POM_VERSION.jar + +java -jar $JAR < $1 | python -mjson.tool diff --git a/framework/src/onos/tools/test/bin/onos-patch-vm b/framework/src/onos/tools/test/bin/onos-patch-vm new file mode 100755 index 00000000..39f1c603 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-patch-vm @@ -0,0 +1,22 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely patches the ONOS VM to tailor its hostname. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +address=${1:-$OCI} +remote=$ONOS_USER@$address +name=${2:-onos-1} + +[ -z "$address" ] && echo "Null address not allowed" >&2 && exit 1 +[ -z "$name" ] && echo "Null name not allowed" >&2 && exit 1 + +ssh $remote " + sudo perl -pi.bak -e \"s/127.0.1.1.*/127.0.1.1 $name/g\" /etc/hosts + sudo bash -c \"echo $name >/etc/hostname\" + sudo hostname $name +" 2>/dev/null + +echo "$address: $(ssh $remote hostname)" diff --git a/framework/src/onos/tools/test/bin/onos-push-bits b/framework/src/onos/tools/test/bin/onos-push-bits new file mode 100755 index 00000000..8c9276fc --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-bits @@ -0,0 +1,19 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely pushes bits to a remote node in preparation for install. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} +remote=$ONOS_USER@$node + +locHash=$(cksum $ONOS_TAR | cut -d' ' -f1,2) +remHash=$(ssh $remote cksum $ONOS_TAR 2>/dev/null | cut -d' ' -f1,2) + +if [ "$locHash" = "$remHash" ]; then + echo "ONOS bits $ONOS_TAR already up-to-date on $node..." +else + scp -q $ONOS_TAR $remote:/tmp +fi diff --git a/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy b/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy new file mode 100755 index 00000000..1ec7107c --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-bits-through-proxy @@ -0,0 +1,22 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely pushes bits to all remote nodes in preparation for install. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +OCT=${OCT:-$OCI} +node=${1:-$OCT} +remote=$ONOS_USER@$node +shift + +echo "Pushing to proxy $node..." +onos-push-bits $node + +others=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2 | grep -v $OCT) + +for other in $others; do + echo "Pushing to $other..." + ssh $remote "scp $ONOS_TAR $ONOS_USER@$other:$ONOS_TAR" +done diff --git a/framework/src/onos/tools/test/bin/onos-push-keys b/framework/src/onos/tools/test/bin/onos-push-keys new file mode 100755 index 00000000..94da6998 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-keys @@ -0,0 +1,19 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Pushes the local id_rsa.pub to the authorized_keys on a remote ONOS node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +remote=$ONOS_USER@${1:-$OCI} + +cat ~/.ssh/id_rsa.pub | ssh $remote " + mkdir -p ~/.ssh + chmod 700 ~/.ssh + cat >> ~/.ssh/authorized_keys + sort -u ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.bak + mv ~/.ssh/authorized_keys.bak ~/.ssh/authorized_keys + chmod 600 ~/.ssh/authorized_keys +" +ssh -n -o PasswordAuthentication=no $remote true diff --git a/framework/src/onos/tools/test/bin/onos-push-test-bits b/framework/src/onos/tools/test/bin/onos-push-test-bits new file mode 100755 index 00000000..927d157f --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-test-bits @@ -0,0 +1,16 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely pushes test bits to a remote test machine and unrolls them in /tmp +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} +remote=$ONOS_USER@$node + +scp -q $ONOS_TEST_TAR $remote:/tmp +ssh $remote " + rm -f /tmp/onos $ONOS_TEST_BITS + cd /tmp && tar zxf $ONOS_TEST_BITS.tar.gz && ln -s $ONOS_TEST_BITS onos +" diff --git a/framework/src/onos/tools/test/bin/onos-push-topos b/framework/src/onos/tools/test/bin/onos-push-topos new file mode 100755 index 00000000..a09d7440 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-topos @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely pushes test topologies a remote mininet test machine. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCN} + +scp -qr $ONOS_ROOT/tools/test/topos $ONOS_USER@$node: diff --git a/framework/src/onos/tools/test/bin/onos-push-update-bundle b/framework/src/onos/tools/test/bin/onos-push-update-bundle new file mode 100755 index 00000000..85fa27bc --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-push-update-bundle @@ -0,0 +1,27 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Pushes the specified bundle to the remote ONOS cell machines and updates it. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +cd ~/.m2/repository +jar=$(find org/onosproject -type f -name '*.jar' | grep -e $1 | grep -v -e -tests | head -n 1) + +[ -z "$jar" ] && echo "No bundle $1 found for" && exit 1 + +bundle=$(echo $(basename $jar .jar) | sed 's/-[0-9].*//g') + +echo "pushing bundle: $bundle" + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) +for node in $nodes; do + scp -q $jar $ONOS_USER@$node:.m2/repository/$jar + scp -q $jar $ONOS_USER@$node:$ONOS_INSTALL_DIR/$KARAF_DIST/system/$jar + ssh $ONOS_USER@$node " + $ONOS_INSTALL_DIR/bin/onos \"bundle:stop -f $bundle\" + $ONOS_INSTALL_DIR/bin/onos \"bundle:update -f $bundle\" + $ONOS_INSTALL_DIR/bin/onos \"bundle:start -f $bundle\" + " 2>/dev/null +done diff --git a/framework/src/onos/tools/test/bin/onos-remove-raft-logs b/framework/src/onos/tools/test/bin/onos-remove-raft-logs new file mode 100755 index 00000000..1f1e5c68 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-remove-raft-logs @@ -0,0 +1,14 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Removes Raft logs on all instances +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + +onos-service --cell stop + +# TODO: use $KARAF_DATA +for node in $nodes; do onos-ssh $node "rm -v -- $ONOS_INSTALL_DIR/$KARAF_DIST/data/raft/onos-copy-cat-log_*"; done diff --git a/framework/src/onos/tools/test/bin/onos-rsdocs b/framework/src/onos/tools/test/bin/onos-rsdocs new file mode 100755 index 00000000..bc0127cf --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-rsdocs @@ -0,0 +1,9 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Launches ONOS REST API docs GUI on the specified node. +# ----------------------------------------------------------------------------- + +host=${1:-$OCI} +host=${host:-localhost} + +open http://$host:8181/onos/v1/docs diff --git a/framework/src/onos/tools/test/bin/onos-secure-ssh b/framework/src/onos/tools/test/bin/onos-secure-ssh new file mode 100755 index 00000000..3c15fa3c --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-secure-ssh @@ -0,0 +1,31 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Secures the ONOS console for all instances in the cell ONOS cluster. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + +for node in $nodes; do + # Setup passwordless login for the remote user on the local bench host + onos-user-key $node + + # Prune the node entry from the known hosts file since server key changes + ssh-keygen -f "$HOME/.ssh/known_hosts" -R [$node]:8101 + + # Setup passwordless login for the local user on the remote node + ssh $ONOS_USER@$node " + [ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q + $ONOS_INSTALL_DIR/bin/onos-user-key \$(id -un) \$(cut -d\\ -f2 ~/.ssh/id_rsa.pub) + $ONOS_INSTALL_DIR/bin/onos-secure-ssh "$@" + + # Implicitly accept the new server key in dev/test environments + while ! ssh -p 8101 -o StrictHostKeyChecking=no localhost list 2>/dev/null; do + echo Waiting for connection... + sleep 1 + done + " +done + diff --git a/framework/src/onos/tools/test/bin/onos-service b/framework/src/onos/tools/test/bin/onos-service new file mode 100755 index 00000000..cc694911 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-service @@ -0,0 +1,55 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely administers the ONOS service on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +function print_usage { + command_name=`basename $0` + echo "Remotely administer the ONOS service on a single node or the current ONOS cell." + echo + echo "Usage: $command_name <TARGET> [COMMAND]" + echo " $command_name [-h | --help]" + echo "Options:" + echo " TARGET The target of the command" + echo " COMMAND The command to execute. Default value is 'status'" + echo " [-h | --help] Print this help" + echo "" + echo "TARGET: <hostname | --cell>" + echo " hostname Execute on the specified host name" + echo " --cell Execute on the current ONOS cell" + echo "" + echo "COMMAND: [start|stop|restart|status]" + echo "" +} + +# Print usage +if [ "${1}" = "-h" -o "${1}" = "--help" ]; then + print_usage + exit 0 +fi + +case $2 in + start|stop|restart|status) + + # Select the target + if [ "${1}" = "--cell" ]; then + nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + else + nodes=$(find_node ${1:-$OCI}) + fi + + # Execute the remote commands + for node in $nodes; do + ssh $ONOS_USER@${node} "sudo ${2:-status} onos" + done + ;; + *) + echo "error: $2 is not a valid command" + echo "" + print_usage + ;; +esac diff --git a/framework/src/onos/tools/test/bin/onos-set-controllers b/framework/src/onos/tools/test/bin/onos-set-controllers new file mode 100755 index 00000000..5b3cd6f7 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-set-controllers @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Sets controllers on all OVS bridges on the mininet machine. +# ----------------------------------------------------------------------------- + +controllers="" + +for node in $ONOS_INSTANCES; do + controllers="$controllers tcp:$node:${OF_PORT:-6633}" +done + +ssh ${ONOS_USER:-sdn}@$OCN " + sudo ovs-vsctl list-br | while read br; do + echo \$br: $controllers + sudo ovs-vsctl set-controller \$br $controllers + done +" diff --git a/framework/src/onos/tools/test/bin/onos-show-cell b/framework/src/onos/tools/test/bin/onos-show-cell new file mode 100755 index 00000000..f5c75726 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-show-cell @@ -0,0 +1,57 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Print the configuration of an ONOS cell. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +function print_usage { + echo "Print the configuration of an ONOS cell." + echo "If no arguments are specified, it will print the configuration for the default" + echo "ONOS cell as specified in the 'ONOS_CELL' environmental variable." + echo + echo "Optional arguments:" + echo " [cell-name] Print the configuration of 'cell-name'" + echo " [-h | --help] Print this help" +} + +if [ "${1}" = "-h" -o "${1}" = "--help" ]; then + print_usage + exit 0 +fi + +if [ -n "${1}" ]; then + cell="${1}" +else + if [ -z "${ONOS_CELL}" ]; then + echo "Environmental variable 'ONOS_CELL' is not defined" + exit 1 + else + cell="${ONOS_CELL}" + fi +fi + +if [ ! -f $ONOS_ROOT/tools/test/cells/${cell} ]; then + echo "No such cell: ${cell}" + exit 1 +fi + +# Load the cell setup +. $ONOS_ROOT/tools/test/cells/${cell} + +echo "ONOS_CELL=${ONOS_CELL}" +echo "ONOS_NIC=${ONOS_NIC}" +# get number of OC variables +max=$( env | egrep 'OC[0-9]+' | wc -l ) +for n in $( seq 0 ${max} ); do + ocn="OC${n}" + if [ -n "${!ocn}" ]; then + echo "$ocn=${!ocn}" + fi +done +echo "OCN=${OCN}" +echo "OCT=${OCT}" +echo "OCI=${OCI}" +echo "ONOS_APPS=${ONOS_APPS}" +echo "ONOS_BOOT_FEATURES=${ONOS_BOOT_FEATURES}" diff --git a/framework/src/onos/tools/test/bin/onos-ssh b/framework/src/onos/tools/test/bin/onos-ssh new file mode 100755 index 00000000..eb6b88e9 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-ssh @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Logs in to the remote ONOS node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +[ -n "$1" ] && OCI=$(find_node $1) && shift +ssh -Y $ONOS_USER@$OCI "$@" diff --git a/framework/src/onos/tools/test/bin/onos-stage-apps b/framework/src/onos/tools/test/bin/onos-stage-apps new file mode 100755 index 00000000..4c2c230e --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-stage-apps @@ -0,0 +1,29 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Stages builtin ONOS apps into the specified directory for packaging. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +export APPS=${1:-/tmp/apps} +export KARAF_M2=${2:-/tmp/karaf/system} +export AUX=$APPS/aux + +# Bail on any errors +set -e + +mkdir -p $APPS $KARAF_M2 +rm -fr $AUX + +find $M2_REPO/org/onosproject/ -name "*.oar" -path "*/${ONOS_POM_VERSION}/*" | while read line; do + mkdir -p $AUX && cd $AUX + cp $line $AUX + jar -xf $AUX/*.oar + name=$(grep "name=" $AUX/app.xml | sed 's/<app name="//g;s/".*//g') + mkdir -p $APPS/$name + cp $AUX/app.xml $APPS/$name/app.xml + cp $AUX/*.oar $APPS/$name/$name.oar + cp -rf $AUX/m2/* $KARAF_M2 + rm -fr $AUX +done diff --git a/framework/src/onos/tools/test/bin/onos-start-network b/framework/src/onos/tools/test/bin/onos-start-network new file mode 100755 index 00000000..1e162fb4 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-start-network @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Verifies connectivity to each node in ONOS cell. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +SSHCMD="ssh -o PasswordAuthentication=no" +SCPCMD="scp -q -o PasswordAuthentication=no" + +echo "Copying topology files to mininet vm." +$SSHCMD -n $ONOS_USER@$OCN mkdir -p topos +$SCPCMD $ONOS_ROOT/tools/test/topos/* $ONOS_USER@$OCN:topos/ + +echo "Starting Network." +$SSHCMD -t $ONOS_USER@$OCN sudo python topos/sol.py $(env | sort | egrep "OC[0-9]+" | cut -d= -f2) diff --git a/framework/src/onos/tools/test/bin/onos-topo-cfg b/framework/src/onos/tools/test/bin/onos-topo-cfg new file mode 100755 index 00000000..5f40d8e7 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-topo-cfg @@ -0,0 +1,14 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS topology configuration uploader. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node="${1:-$OCI}" +file="${2:-$ONOS_ROOT/tools/test/topos/oe-linear-3.json}" + +curl -sS --fail -L --user $ONOS_WEB_USER:$ONOS_WEB_PASS \ + -X POST -H 'Content-Type:application/json' \ + http://$node:8181/onos/v1/config/topology -d@$file diff --git a/framework/src/onos/tools/test/bin/onos-topo-cfg-all b/framework/src/onos/tools/test/bin/onos-topo-cfg-all new file mode 100755 index 00000000..adf84c14 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-topo-cfg-all @@ -0,0 +1,15 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# ONOS topology configuration uploader. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) + +for node in $nodes; do + printf "$node..." + onos-topo-cfg $node $1 +done +printf "\n" diff --git a/framework/src/onos/tools/test/bin/onos-uninstall b/framework/src/onos/tools/test/bin/onos-uninstall new file mode 100755 index 00000000..c04db7ac --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-uninstall @@ -0,0 +1,14 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Remotely stops & uninstalls ONOS on the specified node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +remote=$ONOS_USER@${1:-$OCI} + +ssh $remote " + sudo stop onos 1>/dev/null 2>/dev/null + sudo rm -fr $ONOS_INSTALL_DIR +" diff --git a/framework/src/onos/tools/test/bin/onos-untar-and-run b/framework/src/onos/tools/test/bin/onos-untar-and-run new file mode 100755 index 00000000..f6e8f9b2 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-untar-and-run @@ -0,0 +1,24 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Untars ONOS tar.gz on the remote machine and runs ONOS. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} +remote=$ONOS_USER@$node + +ssh $remote " + [ -d $ONOS_INSTALL_DIR/bin ] && echo \"ONOS is already installed\" && exit 1 + cd /tmp && rm -fr /tmp/$ONOS_BITS + tar zxf /tmp/$ONOS_BITS.tar.gz + + cd /tmp/$ONOS_BITS + export ONOS_NIC=$ONOS_NIC + bin/onos-service server 1>/tmp/onos.out 2>/tmp/onos.err & + + # Setup a few symlinks to allow other tools to work + sudo ln -s /tmp/$ONOS_BITS $ONOS_INSTALL_DIR + sudo ln -s /tmp/$ONOS_BITS/$KARAF_DIST/data/log $ONOS_INSTALL_DIR/log +" diff --git a/framework/src/onos/tools/test/bin/onos-upload-sprites b/framework/src/onos/tools/test/bin/onos-upload-sprites new file mode 100755 index 00000000..982d7132 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-upload-sprites @@ -0,0 +1,18 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Tool to upload GUI sprites definitions using GUI REST API. +# ----------------------------------------------------------------------------- + +node=${1} +sprites=${2} + +if [ -z "$node" -o -z "$sprites" ] +then + echo "Usage: onos-upload-sprites <server-ip> <sprites-defn.json>" + exit 1 +fi + +export URL=http://$node:8181/onos/ui/rs/topology/sprites +export HDR="-HContent-Type:application/json" + +curl --fail -sS -X POST $HDR $URL --data @$sprites diff --git a/framework/src/onos/tools/test/bin/onos-user-key b/framework/src/onos/tools/test/bin/onos-user-key new file mode 100755 index 00000000..b324c1a8 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-user-key @@ -0,0 +1,13 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Adds or removes a user key for managing passwordless loging to ONOS console. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} +user=${2:-$(id -un)} +key=${3:-$(cut -d\ -f2 ~/.ssh/id_rsa.pub)} + +ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-user-key $user $key diff --git a/framework/src/onos/tools/test/bin/onos-verify-cell b/framework/src/onos/tools/test/bin/onos-verify-cell new file mode 100755 index 00000000..4b3a0ee7 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-verify-cell @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Verifies connectivity to each node in ONOS cell. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +for node in $(env | sort | egrep "OC[0-9N]+" | cut -d= -f2); do + printf "%s: " $node; ssh -n -o PasswordAuthentication=no $ONOS_USER@$node date +done diff --git a/framework/src/onos/tools/test/bin/onos-wait-for-start b/framework/src/onos/tools/test/bin/onos-wait-for-start new file mode 100755 index 00000000..e643b5a6 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-wait-for-start @@ -0,0 +1,28 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Waits for ONOS to reach run-level 100 on the specified remote node. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults +. $ONOS_ROOT/tools/test/bin/find-node.sh + +node=$(find_node ${1:-$OCI}) + +remote=$ONOS_USER@$node + +ssh -t $remote " + # Wait until we reach the run-level 100 + for i in \$(seq 1 45); do + $ONOS_INSTALL_DIR/bin/onos bundle:list 2>/dev/null | \ + grep -q 'START LEVEL 100' && break || sleep 2 + done + + # Wait until ApplicationManager is available + for i in \$(seq 1 10); do + grep -q \" ApplicationManager .* Started\" \ + $ONOS_INSTALL_DIR/log/karaf.log && break || sleep 1 + done + + grep -q \" ApplicationManager .* Started\" $ONOS_INSTALL_DIR/log/karaf.log +" diff --git a/framework/src/onos/tools/test/bin/onos-watch b/framework/src/onos/tools/test/bin/onos-watch new file mode 100755 index 00000000..28e88c2f --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-watch @@ -0,0 +1,17 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Monitors selected set of ONOS commands using the system watch command. +# ----------------------------------------------------------------------------- + +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 +. $ONOS_ROOT/tools/build/envDefaults + +node=${1:-$OCI} + +commands="${2:-summary,intents,flows,hosts}" + +aux=/tmp/onos-watch.$$ +trap "rm -f $aux" EXIT + +echo "$commands" | tr ',' '\n' > $aux +watch $3 "onos $node -b <$aux 2>/dev/null" diff --git a/framework/src/onos/tools/test/bin/onos-wipe-out b/framework/src/onos/tools/test/bin/onos-wipe-out new file mode 100755 index 00000000..6e996345 --- /dev/null +++ b/framework/src/onos/tools/test/bin/onos-wipe-out @@ -0,0 +1,9 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Wipes out all data from the ONOS cluster. Temporary until wipe-out is fixed. +# ----------------------------------------------------------------------------- + +for node in ${ONOS_INSTANCES:-$OCI}; do + onos $node wipe-out please +done +onos-check-summary $OCI '.*' 0 0 0 0 0 diff --git a/framework/src/onos/tools/test/bin/stc b/framework/src/onos/tools/test/bin/stc new file mode 100755 index 00000000..fe8a5afe --- /dev/null +++ b/framework/src/onos/tools/test/bin/stc @@ -0,0 +1,23 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# System Test Coordinator +#------------------------------------------------------------------------------- + +VER=1.3.0-SNAPSHOT +JAR=~/.m2/repository/org/onosproject/onlab-stc/$VER/onlab-stc-$VER.jar +SCENARIOS=$ONOS_ROOT/tools/test/scenarios + +DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=y" + +scenario=${1:-smoke} + +[ ! -f $scenario ] && scenario=$SCENARIOS/$scenario +[ ! -f $scenario ] && scenario=$scenario.xml +[ ! -f $scenario ] && echo "Scenario $scenario file not found" && exit 1 + +[ $# -ge 1 ] && shift + +[ -t 1 ] && stcColor=true || unset stcColor + +[ -z "$stcDebug" ] && DEBUG_OPTS="" +java $DEBUG_OPTS -jar $JAR $scenario "$@" diff --git a/framework/src/onos/tools/test/bin/stc-launcher b/framework/src/onos/tools/test/bin/stc-launcher new file mode 100755 index 00000000..6e473cdf --- /dev/null +++ b/framework/src/onos/tools/test/bin/stc-launcher @@ -0,0 +1,25 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# System Test Coordinator process launcher +#------------------------------------------------------------------------------- + +#sleep 5 && exit 0; + +env=$1 && shift +cwd=$1 && shift + +if [ $env != "-" -a $env != "~" ]; then + [ ! -f $env ] && echo "$env file not found" && exit 1 + source $env +fi + +if [ $cwd != "-" ]; then + [ ! -d $cwd ] && echo "$cwd directory not found" && exit 1 + cd $cwd +fi + +"$@" 2>&1 +status=$? + +[ $env != "~" ] && exit $status +exit 0 diff --git a/framework/src/onos/tools/test/bin/stl b/framework/src/onos/tools/test/bin/stl new file mode 100755 index 00000000..1487ab4f --- /dev/null +++ b/framework/src/onos/tools/test/bin/stl @@ -0,0 +1,7 @@ +#!/bin/bash +#------------------------------------------------------------------------------- +# System Test Coordinator +#------------------------------------------------------------------------------- + +log=${2:-*} +less /tmp/stc/$1/${log%.log}.log
\ No newline at end of file diff --git a/framework/src/onos/tools/test/cells/beast b/framework/src/onos/tools/test/cells/beast new file mode 100644 index 00000000..6afd61d1 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast @@ -0,0 +1,18 @@ +# Bare metal cluster (7-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 +export OC4=10.254.1.204 +export OC5=10.254.1.205 +export OC6=10.254.1.206 +export OC7=10.254.1.207 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-1 b/framework/src/onos/tools/test/cells/beast-1 new file mode 100644 index 00000000..698eded7 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-1 @@ -0,0 +1,12 @@ +# Bare metal cluster (1-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-3 b/framework/src/onos/tools/test/cells/beast-3 new file mode 100644 index 00000000..6586ddc3 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-3 @@ -0,0 +1,14 @@ +# Bare metal cluster (3-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/beast-5 b/framework/src/onos/tools/test/cells/beast-5 new file mode 100644 index 00000000..e23f0771 --- /dev/null +++ b/framework/src/onos/tools/test/cells/beast-5 @@ -0,0 +1,18 @@ +# Bare metal cluster (5-node) + +# Use the 1G NIC for cluster communications +export ONOS_NIC="10.254.1.*" + +# ONOS Test proxy +export OCT=10.254.1.200 + +export OCN=10.254.1.200 + +# Use the 1G NICs for external access +export OC1=10.254.1.201 +export OC2=10.254.1.202 +export OC3=10.254.1.203 +export OC4=10.254.1.204 +export OC5=10.254.1.205 + +export ONOS_APPS="drivers,openflow,proxyarp,fwd" diff --git a/framework/src/onos/tools/test/cells/bramble b/framework/src/onos/tools/test/cells/bramble new file mode 100644 index 00000000..7f17d2f5 --- /dev/null +++ b/framework/src/onos/tools/test/cells/bramble @@ -0,0 +1,8 @@ +export ONOS_NIC=192.168.1.* +export OC1="192.168.1.11" +export OC2="192.168.1.12" +export OC3="192.168.1.13" +export OC4="192.168.1.14" +# export OC5="192.168.1.15" +export OCN="192.168.1.15" +export OCI="${OC1}" diff --git a/framework/src/onos/tools/test/cells/ec2 b/framework/src/onos/tools/test/cells/ec2 new file mode 100644 index 00000000..3d64be27 --- /dev/null +++ b/framework/src/onos/tools/test/cells/ec2 @@ -0,0 +1,18 @@ +# EC2-based cluster (7-node) + +# Use the 10G NIC for cluster communications +export ONOS_NIC="192.168.200.*" + +# ONOS Test proxy +export OCT=192.168.200.101 + +# Use the 1G NICs for external access +export OC1=192.168.200.101 +export OC2=192.168.200.102 +export OC3=192.168.200.103 +export OC4=192.168.200.104 +export OC5=192.168.200.105 +export OC6=192.168.200.106 +export OC7=192.168.200.107 + +export ONOS_APPS="drivers,null,intentperf" diff --git a/framework/src/onos/tools/test/cells/local b/framework/src/onos/tools/test/cells/local new file mode 100644 index 00000000..6d8b71cd --- /dev/null +++ b/framework/src/onos/tools/test/cells/local @@ -0,0 +1,8 @@ +# Local VirtualBox-based ONOS instances 1,2 & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OC2="192.168.56.102" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/cells/madan3 b/framework/src/onos/tools/test/cells/madan3 new file mode 100644 index 00000000..857d096e --- /dev/null +++ b/framework/src/onos/tools/test/cells/madan3 @@ -0,0 +1,7 @@ +# Madan's ProxMox ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC="10.128.4.*" +export OC1="10.128.4.2" +export OC2="10.128.4.3" +export OC3="10.128.4.4" +export OCN="10.128.4.5" diff --git a/framework/src/onos/tools/test/cells/office b/framework/src/onos/tools/test/cells/office new file mode 100644 index 00000000..2cd933e2 --- /dev/null +++ b/framework/src/onos/tools/test/cells/office @@ -0,0 +1,7 @@ +# ONLAB_OF Wifi ProxMox-based cell; single node; no mininet-box + +export ONOS_NIC="10.1.10.*" +export OC1="10.1.10.223" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" + diff --git a/framework/src/onos/tools/test/cells/prox b/framework/src/onos/tools/test/cells/prox new file mode 100644 index 00000000..8af41989 --- /dev/null +++ b/framework/src/onos/tools/test/cells/prox @@ -0,0 +1,6 @@ +# ProxMox-based cell of ONOS instances 1,2 & ONOS mininet box + +export ONOS_NIC="10.1.9.*" +export OC1="10.1.9.94" +export OC2="10.1.9.82" +export OCN="10.1.9.93" diff --git a/framework/src/onos/tools/test/cells/sdnip-pmox b/framework/src/onos/tools/test/cells/sdnip-pmox new file mode 100644 index 00000000..e95b7e79 --- /dev/null +++ b/framework/src/onos/tools/test/cells/sdnip-pmox @@ -0,0 +1,8 @@ +# SDN-IP ProxMox cell + +export ONOS_NIC=10.128.4.* +export OC1="10.128.4.65" +export OC2="10.128.4.66" +export OC3="10.128.4.67" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility,config,sdnip" diff --git a/framework/src/onos/tools/test/cells/single b/framework/src/onos/tools/test/cells/single new file mode 100644 index 00000000..dd03e491 --- /dev/null +++ b/framework/src/onos/tools/test/cells/single @@ -0,0 +1,7 @@ +# Local VirtualBox-based single ONOS instance & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/cells/single_optical b/framework/src/onos/tools/test/cells/single_optical new file mode 100644 index 00000000..6bbe176e --- /dev/null +++ b/framework/src/onos/tools/test/cells/single_optical @@ -0,0 +1,7 @@ +# Optical use-case VirtualBox-based single ONOS instance & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility,optical" diff --git a/framework/src/onos/tools/test/cells/tom b/framework/src/onos/tools/test/cells/tom new file mode 100644 index 00000000..28d31729 --- /dev/null +++ b/framework/src/onos/tools/test/cells/tom @@ -0,0 +1,7 @@ +# Thomas' VirtualBox-based 3 ONOS instances & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.11" +export OC2="192.168.56.12" +export OC3="192.168.56.13" +export OCN="192.168.56.7" diff --git a/framework/src/onos/tools/test/cells/tomx b/framework/src/onos/tools/test/cells/tomx new file mode 100644 index 00000000..3e528ee8 --- /dev/null +++ b/framework/src/onos/tools/test/cells/tomx @@ -0,0 +1,10 @@ +# Tom's ProxMox ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC="10.128.11.*" +export OC1="10.128.11.1" +export OC2="10.128.11.2" +export OC3="10.128.11.3" +export OCN="10.128.11.4" + +export OCT=$OC1 +export ONOS_APPS=drivers,openflow,proxyarp
\ No newline at end of file diff --git a/framework/src/onos/tools/test/cells/triple b/framework/src/onos/tools/test/cells/triple new file mode 100644 index 00000000..42471228 --- /dev/null +++ b/framework/src/onos/tools/test/cells/triple @@ -0,0 +1,9 @@ +# Local VirtualBox-based ONOS instances 1,2,3 & ONOS mininet box + +export ONOS_NIC=192.168.56.* +export OC1="192.168.56.101" +export OC2="192.168.56.102" +export OC3="192.168.56.104" +export OCN="192.168.56.103" + +export ONOS_APPS="drivers,openflow,fwd,proxyarp,mobility" diff --git a/framework/src/onos/tools/test/configs/l2-flow.json b/framework/src/onos/tools/test/configs/l2-flow.json new file mode 100644 index 00000000..64bb5297 --- /dev/null +++ b/framework/src/onos/tools/test/configs/l2-flow.json @@ -0,0 +1,28 @@ +{ + "isPermanent": true, + "priority": 100, + "selector": { + "criteria": [ + { + "port": 2, + "type": "IN_PORT" + }, + { + "mac": "00:00:00:00:11:22", + "type": "ETH_SRC" + }, + { + "mac": "00:00:00:00:33:44", + "type": "ETH_DST" + } + ] + }, + "treatment": { + "instructions": [ + { + "port": 1, + "type": "OUTPUT" + } + ] + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/configs/override-basic.json b/framework/src/onos/tools/test/configs/override-basic.json new file mode 100644 index 00000000..c1f23ce6 --- /dev/null +++ b/framework/src/onos/tools/test/configs/override-basic.json @@ -0,0 +1,38 @@ +{ + "devices": { + "of:0000000000000009": { + "basic": { + "allowed": true, + "owner": "Luigi" + } + }, + "of:0000000000000008": { + "basic": { + "name": "NameChangeAgain", + "allowed": true, + "owner": "Mario" + } + }, + "of:0000000000000007": { + "basic": { + "allowed": true, + "owner": "Peach", + "latitude": "25" + } + } + }, + "links": { + "of:0000000000000006/2-of:0000000000000007/2": { + "basic": { + "allowed": true + } + } + }, + "hosts": { + "00:00:00:00:00:03/-1": { + "basic": { + "allowed": true + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/configs/sample-basic.json b/framework/src/onos/tools/test/configs/sample-basic.json new file mode 100644 index 00000000..73cbd305 --- /dev/null +++ b/framework/src/onos/tools/test/configs/sample-basic.json @@ -0,0 +1,54 @@ +{ + "devices": { + "of:0000000000000009": { + "basic": { + "allowed": true, + "owner": "Luigi" + } + }, + "of:0000000000000008": { + "basic": { + "name": "NameChange", + "allowed": true, + "owner": "Mario" + } + }, + "of:0000000000000007": { + "basic": { + "allowed": true, + "owner": "Peach", + "latitude": "25" + } + }, + "of:0000000000000003": { + "basic": { + "allowed": true, + "owner": "Wario" + } + } + }, + "links": { + "of:0000000000000006/2-of:0000000000000007/2": { + "basic": { + "allowed": true + } + } + }, + "hosts": { + "00:00:00:00:00:03/-1": { + "basic": { + "allowed": false + } + }, + "00:00:00:00:00:02/-1": { + "basic": { + "allowed": false + } + }, + "00:00:00:00:00:01/-1": { + "basic": { + "allowed": false + } + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/archetypes.xml b/framework/src/onos/tools/test/scenarios/archetypes.xml new file mode 100644 index 00000000..8244a32f --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/archetypes.xml @@ -0,0 +1,50 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="archetypes" description="ONOS archetypes test"> + <group name="Archetypes" cwd="${WORKSPACE}/tmp/test-app"> + <step name="Clean-Up" cwd="${WORKSPACE}/tmp" env="~" + exec="rm -r test-app"/> + + <step name="Create-App" cwd="${WORKSPACE}/tmp" requires="^" + exec="onos-create-app app org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App" requires="Create-App" exec="mvn clean install"/> + <step name="Install-App" requires="^" + exec="onos-app ${OCI} install! target/test-app-1.2.3.oar"/> + <step name="Verify-App" requires="^" + exec="onos-check-components ${OCI} org.test.app.AppComponent"/> + + <step name="Create-App-CLI-Overlay" requires="Install-App" + exec="onos-create-app cli org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App-With-CLI" requires="^" + exec="mvn clean install"/> + <step name="Reinstall-App-With-CLI" requires="^,~Verify-App" + exec="onos-app ${OCI} reinstall! target/test-app-1.2.3.oar"/> + <step name="Verify-CLI" requires="^" + exec="onos ${OCI} sample"/> + + <step name="Create-App-UI-Overlay" requires="Reinstall-App-With-CLI" + exec="onos-create-app ui org.test.app test-app 1.2.3 org.test.app -DinteractiveMode=false"/> + <step name="Build-App-With-UI" requires="^" + exec="mvn clean install"/> + <step name="Reinstall-App-With-UI" requires="^,~Verify-CLI" + exec="onos-app ${OCI} reinstall! target/test-app-1.2.3.oar"/> + <step name="Verify-UI" requires="^" + exec="onos-check-views ${OCI} id=sample"/> + + <step name="Uninstall-App" requires="^" + exec="onos-app ${OCI} uninstall org.foo.app"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/bin/create-flow.py b/framework/src/onos/tools/test/scenarios/bin/create-flow.py new file mode 100755 index 00000000..4e9b452b --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/create-flow.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python + +import requests + +from requests.auth import HTTPBasicAuth +import sys + + + +if len(sys.argv) != 6: + print "usage: create-flow onos-node name device in-port out-port" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +device = sys.argv[3] +inPort = sys.argv[4] +outPort = sys.argv[5] + +flowJsonTemplate = \ + '{{' + \ + '"priority": 1,' + \ + '"isPermanent": true,' + \ + '"treatment": {{' + \ + '"instructions": [' + \ + '{{' + \ + '"type": "OUTPUT",' + \ + '"port": {}' + \ + '}}' + \ + ']' + \ + '}},' + \ + '"selector": {{' + \ + '"criteria": [' + \ + '{{' + \ + '"type": "IN_PORT",' + \ + '"port": {}' + \ + '}}' + \ + ']' + \ + '}}' + \ + '}}' + +flowJson = flowJsonTemplate.format(inPort, outPort) +intentRequest = requests.post('http://' + node + ':8181/onos/v1/flows/' + device, + auth=HTTPBasicAuth('onos', 'rocks'), + data=flowJson) + +if intentRequest.status_code != 201: + print intentRequest.text + sys.exit(1) + +location = intentRequest.headers["location"] +print "@stc " + name + "Location=" + location +sys.exit(0) + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/create-intent.py b/framework/src/onos/tools/test/scenarios/bin/create-intent.py new file mode 100755 index 00000000..4e5d4f62 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/create-intent.py @@ -0,0 +1,49 @@ +#! /usr/bin/env python + +import requests + +from requests.auth import HTTPBasicAuth +import sys + + + +if len(sys.argv) != 7: + print "usage: create-intent onos-node name ingressDevice ingressPort egressDevice egressPort" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +ingress = sys.argv[3] +ingressPort = sys.argv[4] +egress = sys.argv[5] +egressPort = sys.argv[6] + +intentJsonTemplate = \ + '{{' + \ + '"type": "PointToPointIntent",' + \ + '"appId": "org.onosproject.cli",' + \ + '"ingressPoint": {{' + \ + ' "device": "{}",' + \ + ' "port": "{}"' + \ + '}},' + \ + '"egressPoint": {{' + \ + ' "device": "{}",' + \ + ' "port": "{}"' + \ + '}}' + \ + '}}' + +intentJson = intentJsonTemplate.format(ingress, ingressPort, egress, egressPort) +intentRequest = requests.post('http://' + node + ':8181/onos/v1/intents/', + auth=HTTPBasicAuth('onos', 'rocks'), + data=intentJson) + +if intentRequest.status_code != 201: + print intentRequest.text + sys.exit(1) + +location = intentRequest.headers["location"] +print "@stc " + name + "Location=" + location +sys.exit(0) + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-device.py b/framework/src/onos/tools/test/scenarios/bin/find-device.py new file mode 100755 index 00000000..430e18ad --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-device.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python + +import requests +import sys +import urllib + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-device onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +id = sys.argv[3] + +deviceRequest = requests.get('http://' + node + ':8181/onos/v1/devices/' + + urllib.quote_plus(id), + auth=HTTPBasicAuth('onos', 'rocks')) + +if deviceRequest.status_code != 200: + print deviceRequest.text + sys.exit(1) + +deviceJson = deviceRequest.json() + +print "@stc " + name + "Id=" + deviceJson["id"] +print "@stc " + name + "Type=" + deviceJson["type"] +print "@stc " + name + "Available=" + str(deviceJson["available"]) +channelId = deviceJson["annotations"]["channelId"] +channelIdWords = channelId.split(':') +print "@stc " + name + "IpAddress=" + channelIdWords[0] + +sys.exit(0) + + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-flow.py b/framework/src/onos/tools/test/scenarios/bin/find-flow.py new file mode 100755 index 00000000..a2f2e4d1 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-flow.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python + +import requests +import sys + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-flow onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +deviceId = sys.argv[3] + +flowsRequest = requests.get('http://' + node + ':8181/onos/v1/flows/' + deviceId, + auth=HTTPBasicAuth('onos', 'rocks')) + +if flowsRequest.status_code != 200: + print flowsRequest.text + sys.exit(1) + +flowsJson = flowsRequest.json() + +for flow in flowsJson["flows"]: + if deviceId == flow["deviceId"]: + for criterion in flow["selector"]["criteria"]: + if criterion["type"] == 'IN_PORT' and criterion["port"] > 0: + for instruction in flow["treatment"]["instructions"]: + if instruction["port"] > 0 and instruction["type"] == 'OUTPUT': + print "@stc " + name + "FlowState=" + flow["state"] + print "@stc " + name + "FlowId=" + flow["id"] + print "@stc " + name + "FlowPort=" + str(instruction["port"]) + sys.exit(0) + +sys.exit(1) + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-host.py b/framework/src/onos/tools/test/scenarios/bin/find-host.py new file mode 100755 index 00000000..e87a4090 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-host.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python + +import requests +import sys +import urllib + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 4: + print "usage: find-host onos-node name device-id" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +id = sys.argv[3] + +hostRequest = requests.get('http://' + node + ':8181/onos/v1/hosts/' + + urllib.quote_plus(id), + auth=HTTPBasicAuth('onos', 'rocks')) + +if hostRequest.status_code != 200: + print hostRequest.text + sys.exit(1) + +hostJson = hostRequest.json() + +print "@stc " + name + "Id=" + hostJson["id"] +print "@stc " + name + "Mac=" + hostJson["mac"] +print "@stc " + name + "IpAddress=" + hostJson["ipAddresses"][0] + +sys.exit(0) + + + + + diff --git a/framework/src/onos/tools/test/scenarios/bin/find-link.py b/framework/src/onos/tools/test/scenarios/bin/find-link.py new file mode 100755 index 00000000..9ac6e358 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/bin/find-link.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python + +import requests +import sys + +from requests.auth import HTTPBasicAuth + +if len(sys.argv) != 7: + print "usage: find-link onos-node name src-device-id src-port dst-device-id dst-port" + sys.exit(1) + +node = sys.argv[1] +name = sys.argv[2] +srcDeviceId = sys.argv[3] +srcPort = sys.argv[4] +dstDeviceId = sys.argv[5] +dstPort = sys.argv[6] + + +linksRequest = requests.get('http://' + node + ':8181/onos/v1/links?device=' + + srcDeviceId + '&port=' + srcPort, + auth=HTTPBasicAuth('onos', 'rocks')) + +if linksRequest.status_code != 200: + print linksRequest.text + sys.exit(1) + +linksJson = linksRequest.json() + +for link in linksJson["links"]: + if srcDeviceId == link["src"]["device"]: + if dstDeviceId == link["dst"]["device"]: + print "@stc " + name + "SrcDevice=" + link["src"]["device"] + print "@stc " + name + "SrcPort=" + link["src"]["port"] + print "@stc " + name + "DstDevice=" + link["dst"]["device"] + print "@stc " + name + "DstPort=" + link["dst"]["port"] + print "@stc " + name + "Type=" + link["type"] + print "@stc " + name + "State=" + link["state"] + sys.exit(0) + +sys.exit(1) + + + + diff --git a/framework/src/onos/tools/test/scenarios/example.xml b/framework/src/onos/tools/test/scenarios/example.xml new file mode 100644 index 00000000..65803141 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/example.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="example" description="Example"> + <step name="One" exec="echo @stc foo=bar"/> + <step name="Two" requires="One" exec="echo ${foo}"/> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-create-flows.xml b/framework/src/onos/tools/test/scenarios/net-create-flows.xml new file mode 100644 index 00000000..6a6a80b0 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-create-flows.xml @@ -0,0 +1,93 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-create-flows" + description="Network Flow Creation Test Using REST API"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Create-Flows"> + + <!-- Make sure that reactive forwarding is off --> + <step name="Net-Create-Flows.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Net-Create-Flows.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <!-- Force discovery of hosts --> + <step name="Net-Create-Flows.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect 100% packet loss"/> + <step name="Net-Create-Flows.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect 100% packet loss"/> + + + <!-- Use REST API to create a point to point intent in each direction --> + <step name="Net-Create-Flows.1-to-Host" requires="Net-Create-Flows.Find-Host-2" + exec="create-flow.py ${OC1} f1 of:0000000000000001 5 1"/> + <step name="Net-Create-Flows.1-to-19" requires="^" + exec="create-flow.py ${OC1} f2 of:0000000000000001 1 2"/> + <step name="Net-Create-Flows.19-to-7" requires="^" + exec="create-flow.py ${OC1} f3 of:0000000000000019 2 8"/> + <step name="Net-Create-Flows.7-to-4" requires="^" + exec="create-flow.py ${OC1} f4 of:0000000000000007 2 3"/> + <step name="Net-Create-Flows.4-to-Host" requires="^" + exec="create-flow.py ${OC1} f5 of:0000000000000004 1 3"/> + + <step name="Net-Create-Flows.Host-to-1" requires="^" + exec="create-flow.py ${OC1} f6 of:0000000000000001 1 5"/> + <step name="Net-Create-Flows.19-to-1" requires="^" + exec="create-flow.py ${OC1} f7 of:0000000000000001 2 1"/> + <step name="Net-Create-Flows.7-to-19" requires="^" + exec="create-flow.py ${OC1} f8 of:0000000000000019 8 2"/> + <step name="Net-Create-Flows.4-to-7" requires="^" + exec="create-flow.py ${OC1} f9 of:0000000000000007 3 2"/> + <step name="Net-Create-Flows.Host-to-4" requires="^" + exec="create-flow.py ${OC1} f10 of:0000000000000004 3 1"/> + + <!-- Check that connectivity was established --> + <step name="Net-Create-Flows.Ping-XY" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Net-Create-Flows.Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 0% packet loss"/> + + <!-- Use REST API to remove the flows. --> + <step name="Net-Create-Flows.Delete-f1" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f1Location}"/> + <step name="Net-Create-Flows.Delete-f2" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f2Location}"/> + <step name="Net-Create-Flows.Delete-f3" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f3Location}"/> + <step name="Net-Create-Flows.Delete-f4" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f4Location}"/> + <step name="Net-Create-Flows.Delete-f5" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f5Location}"/> + <step name="Net-Create-Flows.Delete-f6" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f6Location}"/> + <step name="Net-Create-Flows.Delete-f7" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f7Location}"/> + <step name="Net-Create-Flows.Delete-f8" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f8Location}"/> + <step name="Net-Create-Flows.Delete-f9" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f9Location}"/> + <step name="Net-Create-Flows.Delete-f10" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${f10Location}"/> + + <!-- Ping again to be sure the path was removed. --> + <step name="Net-Create-Flows.Fail-Ping-XY" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 100% packet loss"/> + <step name="Net-Create-Flows.Fail-Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 100% packet loss"/> + + + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-host-intent.xml b/framework/src/onos/tools/test/scenarios/net-host-intent.xml new file mode 100644 index 00000000..fbf8c4ab --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-host-intent.xml @@ -0,0 +1,59 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-host-intent" description="Network host intent connectivity test"> + <!-- TODO: parametrize this via recipes --> + <group name="Host-Intent-Connectivity"> + <step name="Host-Intent.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Host-Intent.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <step name="Host-Intent.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="Host-Intent.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <step name="Host-Intent.Create-Intent" requires="^" + exec="onos-create-intent ${OC1} h2h host 00:00:00:00:00:01/-1 00:00:00:00:00:04/-1"/> + <step name="Host-Intent.Validate-Intent-Installed" requires="Host-Intent.Create-Intent" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Host-Intent"/> + <dependency name="Host-Intent.Net-Link-Down-Up" + requires="Host-Intent.Validate-Intent-Installed"/> + + <step name="Host-Intent.Validate-Intent-Installed-Still" requires="Host-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <dependency name="Host-Intent.Link-2-Down" + requires="~Host-Intent.Validate-Intent-Installed-Still" /> + + <step name="Host-Intent.Validate-Intent-Failed" requires="Host-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} h2h FAILED"/> + + <dependency name="Host-Intent.Link-1-Up" + requires="~Host-Intent.Validate-Intent-Failed" /> + + <step name="Host-Intent.Validate-Intent-Installed-Again" requires="Host-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} h2h INSTALLED"/> + + <dependency name="Host-Intent.Ping-4" + requires="~Host-Intent.Validate-Intent-Installed-Again" /> + + <step name="Host-Intent.Remove-Intent" requires="~Host-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli h2h"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-link-down-up.xml b/framework/src/onos/tools/test/scenarios/net-link-down-up.xml new file mode 100644 index 00000000..8bcbfa7f --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-link-down-up.xml @@ -0,0 +1,38 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-link-down-up" description="Network link up-down test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Link-Down-Up"> + <step name="Ping-1" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-1-Down" requires="~Ping-1" + exec="onos-mininet sendAndExpect link s4 s7 down --expect ."/> + <step name="Ping-2" requires="~Link-1-Down" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-2-Down" requires="~Ping-2" + exec="onos-mininet sendAndExpect link s4 s5 down --expect ."/> + <step name="Ping-3" requires="~Link-2-Down" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect 100% packet loss"/> + <step name="Link-1-Up" requires="~Ping-3" + exec="onos-mininet sendAndExpect link s4 s7 up --expect ."/> + <step name="Ping-4" requires="~Link-1-Up" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Link-2-Up" requires="~Ping-4" + exec="onos-mininet sendAndExpect link s4 s5 up --expect ."/> + <step name="Ping-5" requires="~Link-2-Up" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-pingall.xml b/framework/src/onos/tools/test/scenarios/net-pingall.xml new file mode 100644 index 00000000..8968e0dc --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-pingall.xml @@ -0,0 +1,37 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-pingall" description="Network pingall test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Pingall"> + <step name="Install-Apps" + exec="onos ${OC1} app activate org.onosproject.openflow org.onosproject.proxyarp org.onosproject.fwd"/> + <step name="Check-Apps" requires="^" + exec="onos-check-apps ${OC1} drivers,openflow,proxyarp,fwd includes"/> + + <!-- TODO: take this out when initial pingall sweep is 100% --> + <step name="Initial-Ping-All" requires="Check-Apps" + exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600 received"/> + + <step name="Ping-All-And-Verify" requires="Check-Apps,Initial-Ping-All" + exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600/600 received"/> + + <step name="Check-Summary-For-Hosts" requires="~Ping-All-And-Verify" + exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/> + + <step name="Config-Topo" requires="~Check-Summary-For-Hosts" + exec="onos-topo-cfg ${OC1} ${ONOS_ROOT}/tools/test/topos/attmpls.json"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-point-intent.xml b/framework/src/onos/tools/test/scenarios/net-point-intent.xml new file mode 100644 index 00000000..acb8212b --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-point-intent.xml @@ -0,0 +1,77 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-point-intent" + description="Network point to point intent connectivity test"> + <!-- TODO: parametrize this via recipes --> + <group name="P2P-Intent-Connectivity"> + <step name="P2P-Intent.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="P2P-Intent.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <step name="P2P-Intent.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="P2P-Intent.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <step name="P2P-Intent.Create-Intent-XY" requires="^" + exec="onos-create-intent ${OC1} xy point of:0000000000000001/1 of:0000000000000004/1"/> + <step name="P2P-Intent.Create-Intent-YX" requires="^" + exec="onos-create-intent ${OC1} yx point of:0000000000000004/1 of:0000000000000001/1"/> + + <step name="P2P-Intent.Validate-Intent-XY-Installed" requires="^" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed" requires="^" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="P2P-Intent"/> + <dependency name="P2P-Intent.Net-Link-Down-Up" + requires="P2P-Intent.Validate-Intent-XY-Installed, + P2P-Intent.Validate-Intent-YX-Installed"/> + + <step name="P2P-Intent.Validate-Intent-XY-Installed-Still" requires="P2P-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed-Still" requires="P2P-Intent.Link-1-Down" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + + <dependency name="P2P-Intent.Link-2-Down" + requires="~P2P-Intent.Validate-Intent-XY-Installed-Still, + ~P2P-Intent.Validate-Intent-YX-Installed-Still"/> + + <step name="P2P-Intent.Validate-Intent-XY-Failed" requires="P2P-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} xy FAILED"/> + <step name="P2P-Intent.Validate-Intent-YX-Failed" requires="P2P-Intent.Link-2-Down" + exec="onos-check-intent ${OC1} yx FAILED"/> + + <dependency name="P2P-Intent.Link-1-Up" + requires="~P2P-Intent.Validate-Intent-XY-Failed, + ~P2P-Intent.Validate-Intent-YX-Failed" /> + + <step name="P2P-Intent.Validate-Intent-XY-Installed-Again" requires="P2P-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} xy INSTALLED"/> + <step name="P2P-Intent.Validate-Intent-YX-Installed-Again" requires="P2P-Intent.Link-1-Up" + exec="onos-check-intent ${OC1} yx INSTALLED"/> + + <dependency name="P2P-Intent.Ping-4" + requires="~P2P-Intent.Validate-Intent-XY-Installed-Again, + ~P2P-Intent.Validate-Intent-YX-Installed-Again"/> + + <step name="P2P-Intent.Remove-Intent-XY" requires="~P2P-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli xy"/> + <step name="P2P-Intent.Remove-Intent-YX" requires="~P2P-Intent.Net-Link-Down-Up" + exec="onos ${OC1} remove-intent -p org.onosproject.cli yx"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-rest.xml b/framework/src/onos/tools/test/scenarios/net-rest.xml new file mode 100644 index 00000000..fc7b1d08 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-rest.xml @@ -0,0 +1,160 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-rest" + description="Network REST API test"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-REST"> + + <!-- Make sure that reactive forwarding is off --> + <step name="Net-REST.Uninstall-Reactive-Forwarding" + exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/> + <step name="Net-REST.Check-Apps" requires="^" + exec="onos-check-apps ${OC1} fwd,ifwd excludes"/> + + <!-- Force discovery of hosts --> + <step name="Net-REST.Find-Host-1" requires="^" + exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/> + <step name="Net-REST.Find-Host-2" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/> + + <!-- Verify some links using the REST API --> + <step name="Net-REST.Query-Link-1" requires="Net-REST.Find-Host-2" + exec="find-link.py ${OC1} link1 of:0000000000000001 5 of:0000000000000006 4"/> + <step name="Net-REST.Validate-Link-1-State" requires="^" + exec="test '${link1State}' == 'ACTIVE'"/> + <step name="Net-REST.Validate-Link-1-Type" requires="^" + exec="test '${link1Type}' == 'DIRECT'"/> + <step name="Net-REST.Validate-Link-1-Src-Device" requires="^" + exec="test '${link1SrcDevice}' == 'of:0000000000000001'"/> + <step name="Net-REST.Validate-Link-1-Dst-Device" requires="^" + exec="test '${link1DstDevice}' == 'of:0000000000000006'"/> + <step name="Net-REST.Validate-Link-1-Src-Port" requires="^" + exec="test '${link1SrcPort}' == '5'"/> + <step name="Net-REST.Validate-Link-1-Dst-Port" requires="^" + exec="test '${link1DstPort}' == '4'"/> + + <step name="Net-REST.Query-Link-2" requires="Net-REST.Find-Host-2" + exec="find-link.py ${OC1} link2 of:0000000000000019 7 of:0000000000000006 3"/> + <step name="Net-REST.Validate-Link-2-State" requires="^" + exec="test '${link2State}' == 'ACTIVE'"/> + <step name="Net-REST.Validate-Link-2-Type" requires="^" + exec="test '${link2Type}' == 'DIRECT'"/> + <step name="Net-REST.Validate-Link-2-Src-Device" requires="^" + exec="test '${link2SrcDevice}' == 'of:0000000000000019'"/> + <step name="Net-REST.Validate-Link-2-Dst-Device" requires="^" + exec="test '${link2DstDevice}' == 'of:0000000000000006'"/> + <step name="Net-REST.Validate-Link-2-Src-Port" requires="^" + exec="test '${link2SrcPort}' == '7'"/> + <step name="Net-REST.Validate-Link-2-Dst-Port" requires="^" + exec="test '${link2DstPort}' == '3'"/> + + <!-- Verify the hosts using the REST API --> + <step name="Net-REST.Query-Host-1" requires="Net-REST.Find-Host-2" + exec="find-host.py ${OC1} host1 00:00:00:00:00:01/-1"/> + <step name="Net-REST.Validate-Host-1-Id" requires="^" + exec="test '${host1Id}' == '00:00:00:00:00:01/-1'"/> + <step name="Net-REST.Validate-Host-1-Mac" requires="^" + exec="test '${host1Mac}' == '00:00:00:00:00:01'"/> + <step name="Net-REST.Validate-Host-1-Ip" requires="^" + exec="test '${host1IpAddress}' == '10.0.0.1'"/> + + <step name="Net-REST.Query-Host-2" requires="Net-REST.Find-Host-2" + exec="find-host.py ${OC1} host2 00:00:00:00:00:04/-1"/> + <step name="Net-REST.Validate-Host-2-Id" requires="^" + exec="test '${host2Id}' == '00:00:00:00:00:04/-1'"/> + <step name="Net-REST.Validate-Host-2-Mac" requires="^" + exec="test '${host2Mac}' == '00:00:00:00:00:04'"/> + <step name="Net-REST.Validate-Host-2-Ip" requires="^" + exec="test '${host2IpAddress}' == '10.0.0.4'"/> + + <!-- Verify a switch using the REST API --> + <step name="Net-REST.Query-Dev-1" requires="Net-REST.Find-Host-2" + exec="find-device.py ${OC1} dev1 of:0000000000000014"/> + <step name="Net-REST.Validate-Dev1-Id" requires="^" + exec="test '${dev1Id}' == 'of:0000000000000014'"/> + <step name="Net-REST.Validate-Dev1-Type" requires="^" + exec="test '${dev1Type}' == 'SWITCH'"/> + <step name="Net-REST.Validate-Dev1-Available" requires="^" + exec="test '${dev1Available}' == 'True'"/> + <step name="Net-REST.Validate-Dev1-ChannelId" requires="^" + exec="test '${dev1IpAddress}' == '${OCN}'"/> + + <!-- Use REST API to create a point to point intent in each direction --> + <step name="Net-REST.Create-Intent-XY" requires="Net-REST.Find-Host-2" + exec="create-intent.py ${OC1} xy of:0000000000000001 1 of:0000000000000004 1"/> + <step name="Net-REST.Create-Intent-YX" requires="^" + exec="create-intent.py ${OC1} yx of:0000000000000004 1 of:0000000000000001 1"/> + + <!-- Check that the intents can be fetched via the REST API --> + <step name="Net-REST.Validate-Intent-XY-Installed" + requires="Net-REST.Create-Intent-YX" + exec="curl -f -uonos:rocks ${xyLocation}"/> + <step name="Net-REST.Validate-Intent-YX-Installed" + requires="^" + exec="curl -f -uonos:rocks ${yxLocation}"/> + + <!-- Use REST API to query flows created by the intents --> + <step name="Net-REST.Validate-Intent-XY-Flow-Installed" + requires="Net-REST.Create-Intent-YX" + exec="find-flow.py ${OC1} dev1out of:0000000000000001"/> + <step name="Net-REST.Validate-XY-Flow-State" requires="^" + exec="test '${dev1outFlowState}' == 'ADDED' -o '${dev1outFlowState}' == 'PENDING_ADD'"/> + <step name="Net-REST.Validate-XY-Flow-Port" requires="^" + exec="test ${dev1outFlowPort} -ge 1 -a ${dev1outFlowPort} -le 5"/> + + <step name="Net-REST.Validate-Intent-YX-Flow-Installed" requires="Net-REST.Create-Intent-YX" + exec="find-flow.py ${OC1} dev4out of:0000000000000004"/> + <step name="Net-REST.Validate-YX-Flow-State" requires="^" + exec="test '${dev4outFlowState}' == 'ADDED' -o '${dev4outFlowState}' == 'PENDING_ADD'"/> + <step name="Net-REST.Validate-YX-Flow-Port" requires="^" + exec="test '${dev4outFlowPort}' == '3'"/> + + <!-- Check that connectivity was established --> + <step name="Net-REST.Ping-XY" requires="Net-REST.Create-Intent-XY,Net-REST.Create-Intent-YX" + exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/> + <step name="Net-REST.Ping-YX" requires="^" + exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect \ 0% packet loss"/> + + <!-- Remove the intents via the REST API --> + <step name="Net-REST.Delete-Intent-XY" + requires="Net-REST.Validate-Intent-XY-Installed, + Net-REST.Validate-Intent-YX-Installed, + Net-REST.Validate-Intent-XY-Flow-Installed, + Net-REST.Validate-Intent-YX-Flow-Installed, + Net-REST.Ping-XY, + Net-REST.Ping-YX" + exec="curl -f -X DELETE -uonos:rocks ${xyLocation}"/> + <step name="Net-REST.Delete-Intent-YX" requires="^" + exec="curl -f -X DELETE -uonos:rocks ${yxLocation}"/> + + <!-- Use REST API to be sure that flows are no longer installed --> + <step name="Net-REST.Validate-XY-Flows-Removed" requires="Net-REST.Delete-Intent-XY" + exec="find-flow.py ${OC1} dev1out of:0000000000000001" + env="!"/> + <step name="Net-REST.Validate-YX-Flows-Removed" requires="Net-REST.Delete-Intent-YX" + exec="find-flow.py ${OC1} dev4out of:0000000000000004" + env="!"/> + + <!-- Check that the deleted intents no longer appear in the REST API --> + <step name="Net-REST.Allow-Intents-To-Purge" requires="Net-REST.Delete-Intent-XY" + exec="sleep 1"/> + <step name="Net-REST.Validate-Intent-XY-Removed" requires="Net-REST.Allow-Intents-To-Purge" + exec="curl -f -uonos:rocks ${xyLocation}" env="!"/> + <step name="Net-REST.Validate-Intent-YX-Removed" requires="Net-REST.Allow-Intents-To-Purge" + exec="curl -f -uonos:rocks ${yxLocation}" env="!"/> + + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-setup.xml b/framework/src/onos/tools/test/scenarios/net-setup.xml new file mode 100644 index 00000000..e179ec5a --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-setup.xml @@ -0,0 +1,46 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-setup" description="Network setup steps"> + <!-- TODO: parametrize this via recipes --> + <group name="Net-Setup"> + <step name="Push-Topos" exec="onos-push-topos ${OCN}"/> + <step name="Stop-Mininet-If-Needed" env="~" exec="onos-mininet stop"/> + + <step name="Wipe-Out-Data-Before" exec="onos-wipe-out"/> + + <step name="Initial-Summary-Check" requires="~Wipe-Out-Data-Before" + exec="onos-check-summary ${OC1} [0-9]* 0 0 0"/> + + <step name="Start-Mininet" + requires="Install-Apps,Initial-Summary-Check,Push-Topos,Stop-Mininet-If-Needed" + exec="onos-mininet start topos/topo att-onos.py ${ONOS_INSTANCES}"/> + + <step name="Wait-For-Mininet" requires="Start-Mininet" + exec="onos-mininet wait 10"/> + + <step name="Check-Summary" requires="Wait-For-Mininet" + exec="onos-check-summary ${OC1} [0-9]* 25 140 0"/> + + <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}" + exec="onos ${OC1} balance-masters"/> + + <step name="Pause-For-Masters" requires="Balance-Masters" if="${OC2}" + exec="sleep 10"/> + + <step name="Check-Flows" requires="~Pause-For-Masters,~Check-Summary" + exec="onos-check-flows ${OC1}"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/net-smoke.xml b/framework/src/onos/tools/test/scenarios/net-smoke.xml new file mode 100644 index 00000000..53a5729c --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-smoke.xml @@ -0,0 +1,44 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-smoke" description="Basic network functionality smoke test"> + <group name="Net-Smoke"> + <import file="${ONOS_SCENARIOS}/net-setup.xml"/> + + <import file="${ONOS_SCENARIOS}/net-pingall.xml" namespace="Reactive-Forwarding"/> + <dependency name="Reactive-Forwarding.Net-Pingall" requires="Net-Setup"/> + + <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Reactive-Forwarding"/> + <dependency name="Reactive-Forwarding.Net-Link-Down-Up" requires="Net-Setup,~Reactive-Forwarding.Net-Pingall"/> + + <import file="${ONOS_SCENARIOS}/net-host-intent.xml"/> + <dependency name="Host-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up"/> + + <import file="${ONOS_SCENARIOS}/net-point-intent.xml"/> + <dependency name="P2P-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up,Host-Intent-Connectivity"/> + + <import file="${ONOS_SCENARIOS}/net-rest.xml"/> + <dependency name="Net-REST" requires="Net-Setup,P2P-Intent-Connectivity"/> + + <import file="${ONOS_SCENARIOS}/net-create-flows.xml"/> + <dependency name="Net-Create-Flows" requires="Net-Setup,P2P-Intent-Connectivity,Net-REST"/> + + <import file="${ONOS_SCENARIOS}/net-teardown.xml"/> + <dependency name="Net-Teardown" requires="~Host-Intent-Connectivity, + ~P2P-Intent-Connectivity, + ~Net-REST, + ~Net-Create-Flows"/> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/net-teardown.xml b/framework/src/onos/tools/test/scenarios/net-teardown.xml new file mode 100644 index 00000000..a5d93ee2 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/net-teardown.xml @@ -0,0 +1,21 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="net-setup" description="Network teardown steps"> + <group name="Net-Teardown"> + <step name="Stop-Mininet" exec="onos-mininet stop"/> + <XXXstep name="Wipe-Out-Data-After" requires="~Stop-Mininet" exec="onos-wipe-out"/> + </group> +</scenario>
\ No newline at end of file diff --git a/framework/src/onos/tools/test/scenarios/prerequisites.xml b/framework/src/onos/tools/test/scenarios/prerequisites.xml new file mode 100644 index 00000000..650aa411 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/prerequisites.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="prerequisites" description="ONOS test pre-requisites"> + <group name="Prerequisites"> + <step name="Check-Environment" exec="test -n ${ONOS_ROOT} -a -n ${ONOS_NIC} -a -n ${OC1}"/> + <step name="Check-ONOS-Bits" exec="onos-check-bits"/> + + <parallel var="${OC#}"> + <step name="Check-Passwordless-Login-${#}" + exec="ssh -n -o ConnectTimeout=3 -o PasswordAuthentication=no sdn@${OC#} date"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/setup.xml b/framework/src/onos/tools/test/scenarios/setup.xml new file mode 100644 index 00000000..c26c0dea --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/setup.xml @@ -0,0 +1,47 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="setup" description="ONOS cluster setup"> + <group name="Setup"> + <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/> + <step name="Secure-SSH" exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS}" if="${ONOS_USE_SSH}"/> + + <parallel var="${OC#}"> + <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" + unless="${OCT}"/> + <step name="Uninstall-${#}" exec="onos-uninstall ${OC#}"/> + <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}" + requires="Uninstall-${#}"/> + + <step name="Install-${#}" exec="onos-install ${OC#}" + requires="Kill-${#},Push-Bits-${#},Push-Bits"/> + + <dependency name="Secure-SSH" requires="Install-${#}"/> + + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Install-${#},~Secure-SSH"/> + + <step name="Check-Nodes-${#}" exec="onos-check-nodes ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Components-${#}" + exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-${#},"/> + <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/shutdown.xml b/framework/src/onos/tools/test/scenarios/shutdown.xml new file mode 100644 index 00000000..0be21647 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/shutdown.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="shutdown" description="ONOS cluster shutdown"> + <group name="Shutdown"> + <parallel var="${OC#}"> + <step name="Stop-Service-${#}" exec="onos-service ${OC#} stop"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Stop-Service-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/smoke.xml b/framework/src/onos/tools/test/scenarios/smoke.xml new file mode 100644 index 00000000..ce8140ad --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/smoke.xml @@ -0,0 +1,30 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="smoke" description="ONOS smoke test"> + <import file="${ONOS_SCENARIOS}/prerequisites.xml"/> + + <import file="${ONOS_SCENARIOS}/setup.xml"/> + <dependency name="Setup" requires="Prerequisites"/> + + <import file="${ONOS_SCENARIOS}/net-smoke.xml"/> + <dependency name="Net-Smoke" requires="Setup"/> + + <import file="${ONOS_SCENARIOS}/archetypes.xml"/> + <dependency name="Archetypes" requires="Setup"/> + + <import file="${ONOS_SCENARIOS}/wrapup.xml"/> + <dependency name="Wrapup" requires="~Archetypes,~Setup,~Net-Smoke"/> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/startup.xml b/framework/src/onos/tools/test/scenarios/startup.xml new file mode 100644 index 00000000..430d51c3 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/startup.xml @@ -0,0 +1,26 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="startup" description="ONOS cluster startup"> + <group name="Startup"> + <parallel var="${OC#}"> + <step name="Start-Service-${#}" exec="onos-service ${OC#} start"/> + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Start-Service-${#}"/> + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/tar-setup.xml b/framework/src/onos/tools/test/scenarios/tar-setup.xml new file mode 100644 index 00000000..e330b2df --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/tar-setup.xml @@ -0,0 +1,64 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="tar-setup" description="ONOS cluster setup via onos.tar.gz"> + <group name="Setup-Instances"> + <step name="Push-Bits" exec="onos-push-bits-through-proxy" if="${OCT}"/> + <step name="Secure-SSH" exec="onos-secure-ssh -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS}" if="${ONOS_USE_SSH}"/> + + <parallel var="${OC#}"> + <step name="Push-Bits-${#}" exec="onos-push-bits ${OC#}" unless="${OCT}"/> + <step name="Uninstall-${#}" exec="onos-uninstall ${OC#}"/> + <step name="Kill-${#}" env="~" exec="onos-kill ${OC#}" requires="Uninstall-${#}"/> + + <step name="Untar-And-Run-${#}" exec="onos-untar-and-run ${OC#}" + requires="Kill-${#},Push-Bits-${#},Push-Bits"/> + + <dependency name="Secure-SSH" requires="Untar-And-Run-${#}"/> + + <step name="Wait-for-Start-${#}" exec="onos-wait-for-start ${OC#}" + requires="Untar-And-Run-${#},~Secure-SSH"/> + + <step name="Check-Logs-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Components-${#}" exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-${#}"/> + <step name="Check-Apps-${#}" exec="onos-check-apps ${OC#} drivers" + requires="~Wait-for-Start-${#}"/> + + <step name="Check-Nodes-${#}" exec="onos-check-nodes ${OC#} ${OC#}" + requires="~Wait-for-Start-${#}"/> + </parallel> + </group> + + <group name="Setup-Cluster" requires="Setup-Instances" unless="${NO_CLUSTER}"> + <step name="Form-Cluster" exec="onos-form-cluster -u ${ONOS_WEB_USER} -p ${ONOS_WEB_PASS} cell"/> + <parallel var="${OC#}"> + <step name="Wait-for-Start-Again-${#}" exec="onos-wait-for-start ${OC#}" + requires="Form-Cluster"/> + + <step name="Check-Logs-Again-${#}" exec="onos-check-logs ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + <step name="Check-Components-Again-${#}" exec="onos-check-components ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + <step name="Check-Apps-Again-${#}" exec="onos-check-apps ${OC#} drivers" + requires="~Wait-for-Start-Again-${#}"/> + + <step name="Check-Nodes-Again-${#}" exec="onos-check-nodes ${OC#}" + requires="~Wait-for-Start-Again-${#}"/> + </parallel> + </group> + +</scenario> diff --git a/framework/src/onos/tools/test/scenarios/wrapup.xml b/framework/src/onos/tools/test/scenarios/wrapup.xml new file mode 100644 index 00000000..e46441d6 --- /dev/null +++ b/framework/src/onos/tools/test/scenarios/wrapup.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ 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. + --> +<scenario name="wrapup" description="ONOS test wrapup"> + <group name="Wrapup"> + <parallel var="${OC#}"> + <step name="Final-Check-Logs-${#}" exec="onos-check-logs ${OC#}"/> + <step name="Fetch-Logs-${#}" exec="onos-fetch-logs ${OC#}" + cwd="${WORKSPACE}/tmp/stc" requires="~^"/> + </parallel> + </group> +</scenario> diff --git a/framework/src/onos/tools/test/topos/att-onos b/framework/src/onos/tools/test/topos/att-onos new file mode 100755 index 00000000..9ad918a9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos @@ -0,0 +1,10 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts ATT ONOS topology in mininet. +# ----------------------------------------------------------------------------- +cd $(dirname $0) +if [ -n "$1" ]; then + sudo python att-onos.py "$@" +else + sudo python att-onos.py 10.128.11.1 10.128.11.2 10.128.11.3 +fi diff --git a/framework/src/onos/tools/test/topos/att-onos-ext.py b/framework/src/onos/tools/test/topos/att-onos-ext.py new file mode 100644 index 00000000..a058b648 --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos-ext.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.link import TCLink + +from attmplsext import AttMplsTopoExt + +setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + net = Mininet( topo=AttMplsTopoExt(), link=TCLink, build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: att-onos-ext.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/att-onos.py b/framework/src/onos/tools/test/topos/att-onos.py new file mode 100644 index 00000000..109d335d --- /dev/null +++ b/framework/src/onos/tools/test/topos/att-onos.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.link import TCLink + +from attmpls import AttMplsTopo + +setLogLevel( 'info' ) + +def pingloop( net ): + setLogLevel( 'error' ) + try: + while True: + net.ping() + finally: + setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + Mininet.pingloop = pingloop + net = Mininet( topo=AttMplsTopo(), link=TCLink, build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + ctrl_count = ctrl_count + 1 + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: att-onos.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/attcli.py b/framework/src/onos/tools/test/topos/attcli.py new file mode 100644 index 00000000..19453204 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attcli.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +""" +CLI for test with AttMplsTopo +""" + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.util import quietRun +from mininet.log import setLogLevel, info, output, error +from mininet.node import RemoteController + +from attmplsfast import AttMplsTopo + +from subprocess import PIPE, STDOUT +from time import time +import random + +class IperfCLI( CLI ): + "CLI with iperf UDP traffic generation" + + def __init__( self, net, *args, **kwargs ): + self.iperfs = {} + self.bw = '12k' + self.mn = net + self.lastbw = {} # last bandwidth reports + self.start() + quietRun( 'rm /tmp/*.iperf /tmp/*.client' ) + CLI.__init__( self, net, *args, **kwargs ) + + def __del__( self ): + "Destructor: kill *all* iperf servers and clients!" + quietRun( 'pkill -9 iperf' ) + + def start( self ): + "Start iperf servers" + for h in sorted( self.mn.hosts ): + with open( '/tmp/%s.iperf' % h, 'w' ) as f: + cmd = 'iperf -f k -i 1 -s -u' + popen = h.popen( cmd, stdin=PIPE, stdout=f, stderr=STDOUT ) + self.iperfs[ h ] = popen + + def udpstart( self, h1, h2, bw): + "Start up a udp iperf from h1 to h2 with bandwidth bw" + # For udp we don't have to wait for startup + self.udpstop( h1 ) + h1.cmdPrint( 'iperf -c', h2.IP(), + '-t 36000 -u -b', bw, + '1>/tmp/%s.client 2>&1 &' % h1 ) + + def udpstop( self, h ): + "udpstop h: Stop udp client on host h" + h.cmdPrint( 'kill %iperf && wait %iperf' ) + h.cmdPrint( 'rm /tmp/%s.client' % h ) + + def do_udp( self, line ): + """udp h1 h2 [rate]: start a udp iperf session from h1 to h2 + rate: udp transmit rate [12k]""" + args = line.split() + if len( args ) not in ( 2, 3 ): + error( 'usage: udp h1 h2 [rate]\n' ) + return + h1, h2 = self.mn.get( *args[ :2 ] ) + bw = self.bw if len( args ) == 2 else args[ 2 ] + self.udpstart( h1, h2, bw ) + + def do_stop( self, line ): + "stop [host | all]: Stop iperf client on host" + if not line or line == 'all': + hosts = self.mn.hosts + else: + hosts = [ self.mn.get( line ) ] + for h in hosts: + self.udpstop( h ) + + def do_bw( self, line ): + "bw: show last reported iperf server ingress bandwidth" + output( "Last reported iperf UDP server input bandwidth:\n" ) + for h in self.mn.hosts: + lastout, lasttime = self.lastbw.get( h, ( '', 0 ) ) + out = h.cmd( 'tail -1 /tmp/%s.iperf' % h ) + if '---' in out or ( out == lastout and + time() - lasttime > 1.5 ): + # Stale update - don't display + out = '\n' + else: + self.lastbw[ h ] = ( out, time() ) + output( '%s:' % h, out ) + + def do_rand( self, line ): + """rand [N [bw]]: Start N random flows (default: 10) + at the given bandwidth (default: 12k) + Note: this may replace existing flows""" + args = line.split() + N = 10 + if args: + try: + N = int( args[ 0 ] ) + except: + error( 'please specify an integer' ) + return + output( 'Starting/restarting', N, 'random flows...\n' ) + bw = self.bw if len( args ) < 2 else args[ 1 ] + servers = random.sample( self.mn.hosts, N ) + clients = [] + for server in servers: + allclients = [ h for h in self.mn.hosts + if h not in clients ] + client = random.choice( allclients ) + clients.append( client ) + self.udpstart( client, server, bw ) + + def do_jobs( self, line ): + "jobs: List iperf jobs" + output( "Currently running jobs:\n" ) + for h in self.mn.hosts: + output( '%s:' % h, h.cmd( 'jobs' ).strip(), '\n' ) + + +def run( Topo=AttMplsTopo ): + "Create network and run CLI" + topo = Topo() + net = Mininet( topo=topo, controller=RemoteController ) + net.start() + info( '\n### Welcome to the custom iperf udp CLI!\n' + '###\n' + '### udp h1 h2 [bw] start iperf udp from h1 to h2\n' + '### stop h1 h2 stop iperf udp from h1 to h2\n' + '### rand [N] start/restart N random udp iperfs\n' + '### bw show last reported udp ingress bandwidth\n' + '### jobs list iperf jobs\n\n' ) + IperfCLI( net ) + net.stop() + + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() diff --git a/framework/src/onos/tools/test/topos/attmpls-intents b/framework/src/onos/tools/test/topos/attmpls-intents new file mode 100755 index 00000000..f4624595 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls-intents @@ -0,0 +1,8 @@ +#!/bin/bash +# Creates some sample intents +onos $OCI add-host-intent 00:00:00:00:00:15/-1 00:00:00:00:00:0b/-1 +onos $OCI add-host-intent 00:00:00:00:00:15/-1 00:00:00:00:00:0e/-1 +onos $OCI add-host-intent 00:00:00:00:00:10/-1 00:00:00:00:00:0a/-1 +onos $OCI add-host-intent 00:00:00:00:00:09/-1 00:00:00:00:00:0c/-1 +onos $OCI add-host-intent 00:00:00:00:00:02/-1 00:00:00:00:00:0e/-1 +onos $OCI add-host-intent 00:00:00:00:00:11/-1 00:00:00:00:00:05/-1 diff --git a/framework/src/onos/tools/test/topos/attmpls.json b/framework/src/onos/tools/test/topos/attmpls.json new file mode 100644 index 00000000..096a78fa --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls.json @@ -0,0 +1,58 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "mac": "000000000001", "annotations": { "name": "CMBR", "latitude": 42.373730, "longitude": -71.109734 }, "type": "SWITCH" }, + { "alias": "s2", "uri": "of:0000000000000002", "mac": "000000000002", "annotations": { "name": "CHCG", "latitude": 41.877461, "longitude": -87.642892 }, "type": "SWITCH" }, + { "alias": "s3", "uri": "of:0000000000000003", "mac": "000000000003", "annotations": { "name": "CLEV", "latitude": 41.498928, "longitude": -81.695217 }, "type": "SWITCH" }, + { "alias": "s4", "uri": "of:0000000000000004", "mac": "000000000004", "annotations": { "name": "RLGH", "latitude": 35.780150, "longitude": -78.644026 }, "type": "SWITCH" }, + { "alias": "s5", "uri": "of:0000000000000005", "mac": "000000000005", "annotations": { "name": "ATLN", "latitude": 33.749017, "longitude": -84.394168 }, "type": "SWITCH" }, + { "alias": "s6", "uri": "of:0000000000000006", "mac": "000000000006", "annotations": { "name": "PHLA", "latitude": 39.952906, "longitude": -75.172278 }, "type": "SWITCH" }, + { "alias": "s7", "uri": "of:0000000000000007", "mac": "000000000007", "annotations": { "name": "WASH", "latitude": 38.906696, "longitude": -77.035509 }, "type": "SWITCH" }, + { "alias": "s8", "uri": "of:0000000000000008", "mac": "000000000008", "annotations": { "name": "NSVL", "latitude": 36.166410, "longitude": -86.787305 }, "type": "SWITCH" }, + { "alias": "s9", "uri": "of:0000000000000009", "mac": "000000000009", "annotations": { "name": "STLS", "latitude": 38.626418, "longitude": -90.198143 }, "type": "SWITCH" }, + { "alias": "s10", "uri": "of:000000000000000a", "mac": "00000000000a", "annotations": { "name": "NWOR", "latitude": 29.951475, "longitude": -90.078434 }, "type": "SWITCH" }, + { "alias": "s11", "uri": "of:000000000000000b", "mac": "00000000000b", "annotations": { "name": "HSTN", "latitude": 29.763249, "longitude": -95.368332 }, "type": "SWITCH" }, + { "alias": "s12", "uri": "of:000000000000000c", "mac": "00000000000c", "annotations": { "name": "SNAN", "latitude": 29.424331, "longitude": -98.491745 }, "type": "SWITCH" }, + { "alias": "s13", "uri": "of:000000000000000d", "mac": "00000000000d", "annotations": { "name": "DLLS", "latitude": 32.777665, "longitude": -96.802064 }, "type": "SWITCH" }, + { "alias": "s14", "uri": "of:000000000000000e", "mac": "00000000000e", "annotations": { "name": "ORLD", "latitude": 28.538641, "longitude": -81.381110 }, "type": "SWITCH" }, + { "alias": "s15", "uri": "of:000000000000000f", "mac": "00000000000f", "annotations": { "name": "DNVR", "latitude": 39.736623, "longitude": -104.984887 }, "type": "SWITCH" }, + { "alias": "s16", "uri": "of:0000000000000010", "mac": "000000000010", "annotations": { "name": "KSCY", "latitude": 39.100725, "longitude": -94.581228 }, "type": "SWITCH" }, + { "alias": "s17", "uri": "of:0000000000000011", "mac": "000000000011", "annotations": { "name": "SNFN", "latitude": 37.779751, "longitude": -122.409791 }, "type": "SWITCH" }, + { "alias": "s18", "uri": "of:0000000000000012", "mac": "000000000012", "annotations": { "name": "SCRM", "latitude": 38.581001, "longitude": -121.497844 }, "type": "SWITCH" }, + { "alias": "s19", "uri": "of:0000000000000013", "mac": "000000000013", "annotations": { "name": "PTLD", "latitude": 45.523317, "longitude": -122.677768 }, "type": "SWITCH" }, + { "alias": "s20", "uri": "of:0000000000000014", "mac": "000000000014", "annotations": { "name": "STTL", "latitude": 47.607326, "longitude": -122.331786 }, "type": "SWITCH" }, + { "alias": "s21", "uri": "of:0000000000000015", "mac": "000000000015", "annotations": { "name": "SLKC", "latitude": 40.759577, "longitude": -111.895079 }, "type": "SWITCH" }, + { "alias": "s22", "uri": "of:0000000000000016", "mac": "000000000016", "annotations": { "name": "LA03", "latitude": 34.056346, "longitude": -118.235951 }, "type": "SWITCH" }, + { "alias": "s23", "uri": "of:0000000000000017", "mac": "000000000017", "annotations": { "name": "SNDG", "latitude": 32.714564, "longitude": -117.153528 }, "type": "SWITCH" }, + { "alias": "s24", "uri": "of:0000000000000018", "mac": "000000000018", "annotations": { "name": "PHNX", "latitude": 33.448289, "longitude": -112.076299 }, "type": "SWITCH" }, + { "alias": "s25", "uri": "of:0000000000000019", "mac": "000000000019", "annotations": { "name": "NY54", "latitude": 40.728270, "longitude": -73.994483 }, "type": "SWITCH" } + ], + + "hosts": [ + { "alias": "h1", "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000000000000001/1", "ip": "10.0.0.1", "annotations": { "name": "CMBR", "latitude": 43.355715, "longitude": -69.528243 } }, + { "alias": "h2", "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000000000000002/1", "ip": "10.0.0.2", "annotations": { "name": "CHCG", "latitude": 43.632679, "longitude": -88.772526 } }, + { "alias": "h3", "mac": "00:00:00:00:00:03", "vlan": -1, "location": "of:0000000000000003/1", "ip": "10.0.0.3", "annotations": { "name": "CLEV", "latitude": 42.756945, "longitude": -79.831317 } }, + { "alias": "h4", "mac": "00:00:00:00:00:04", "vlan": -1, "location": "of:0000000000000004/1", "ip": "10.0.0.4", "annotations": { "name": "RLGH", "latitude": 36.972249, "longitude": -76.667163 } }, + { "alias": "h5", "mac": "00:00:00:00:00:05", "vlan": -1, "location": "of:0000000000000005/1", "ip": "10.0.0.5", "annotations": { "name": "ATLN", "latitude": 35.427493, "longitude": -83.885831 } }, + { "alias": "h6", "mac": "00:00:00:00:00:06", "vlan": -1, "location": "of:0000000000000006/1", "ip": "10.0.0.6", "annotations": { "name": "PHLA", "latitude": 39.208113, "longitude": -73.421341 } }, + { "alias": "h7", "mac": "00:00:00:00:00:07", "vlan": -1, "location": "of:0000000000000007/1", "ip": "10.0.0.7", "annotations": { "name": "WASH", "latitude": 40.133860, "longitude": -79.238299 } }, + { "alias": "h8", "mac": "00:00:00:00:00:08", "vlan": -1, "location": "of:0000000000000008/1", "ip": "10.0.0.8", "annotations": { "name": "NSVL", "latitude": 37.407589, "longitude": -84.415068 } }, + { "alias": "h9", "mac": "00:00:00:00:00:09", "vlan": -1, "location": "of:0000000000000009/1", "ip": "10.0.0.9", "annotations": { "name": "STLS", "latitude": 40.066810, "longitude": -90.932405 } }, + { "alias": "h10", "mac": "00:00:00:00:00:0a", "vlan": -1, "location": "of:000000000000000a/1", "ip": "10.0.0.10", "annotations": { "name": "NWOR", "latitude": 31.470982, "longitude": -88.779353 } }, + { "alias": "h11", "mac": "00:00:00:00:00:0b", "vlan": -1, "location": "of:000000000000000b/1", "ip": "10.0.0.11", "annotations": { "name": "HSTN", "latitude": 31.136858, "longitude": -94.351656 } }, + { "alias": "h12", "mac": "00:00:00:00:00:0c", "vlan": -1, "location": "of:000000000000000c/1", "ip": "10.0.0.12", "annotations": { "name": "SNAN", "latitude": 28.040975, "longitude": -99.169527 } }, + { "alias": "h13", "mac": "00:00:00:00:00:0d", "vlan": -1, "location": "of:000000000000000d/1", "ip": "10.0.0.13", "annotations": { "name": "DLLS", "latitude": 31.899825, "longitude": -99.287263 } }, + { "alias": "h14", "mac": "00:00:00:00:00:0e", "vlan": -1, "location": "of:000000000000000e/1", "ip": "10.0.0.14", "annotations": { "name": "ORLD", "latitude": 26.670509, "longitude": -81.291920 } }, + { "alias": "h15", "mac": "00:00:00:00:00:0f", "vlan": -1, "location": "of:000000000000000f/1", "ip": "10.0.0.15", "annotations": { "name": "DNVR", "latitude": 40.888148, "longitude": -103.459878 } }, + { "alias": "h16", "mac": "00:00:00:00:00:10", "vlan": -1, "location": "of:0000000000000010/1", "ip": "10.0.0.16", "annotations": { "name": "KSCY", "latitude": 40.545088, "longitude": -93.734002 } }, + { "alias": "h17", "mac": "00:00:00:00:00:11", "vlan": -1, "location": "of:0000000000000011/1", "ip": "10.0.0.17", "annotations": { "name": "SNFN", "latitude": 39.081743, "longitude": -124.330172 } }, + { "alias": "h18", "mac": "00:00:00:00:00:12", "vlan": -1, "location": "of:0000000000000012/1", "ip": "10.0.0.18", "annotations": { "name": "SCRM", "latitude": 40.107468, "longitude": -120.424689 } }, + { "alias": "h19", "mac": "00:00:00:00:00:13", "vlan": -1, "location": "of:0000000000000013/1", "ip": "10.0.0.19", "annotations": { "name": "PTLD", "latitude": 44.383051, "longitude": -124.767594 } }, + { "alias": "h20", "mac": "00:00:00:00:00:14", "vlan": -1, "location": "of:0000000000000014/1", "ip": "10.0.0.20", "annotations": { "name": "STTL", "latitude": 48.832627, "longitude": -120.298441 } }, + { "alias": "h21", "mac": "00:00:00:00:00:15", "vlan": -1, "location": "of:0000000000000015/1", "ip": "10.0.0.21", "annotations": { "name": "SLKC", "latitude": 42.301734, "longitude": -111.217297 } }, + { "alias": "h22", "mac": "00:00:00:00:00:16", "vlan": -1, "location": "of:0000000000000016/1", "ip": "10.0.0.22", "annotations": { "name": "LA03", "latitude": 33.224634, "longitude": -121.532943 } }, + { "alias": "h23", "mac": "00:00:00:00:00:17", "vlan": -1, "location": "of:0000000000000017/1", "ip": "10.0.0.23", "annotations": { "name": "SNDG", "latitude": 31.834607, "longitude": -118.847982 } }, + { "alias": "h24", "mac": "00:00:00:00:00:18", "vlan": -1, "location": "of:0000000000000018/1", "ip": "10.0.0.24", "annotations": { "name": "PHNX", "latitude": 34.662290, "longitude": -110.946662 } }, + { "alias": "h25", "mac": "00:00:00:00:00:19", "vlan": -1, "location": "of:0000000000000019/1", "ip": "10.0.0.25", "annotations": { "name": "NY54", "latitude": 42.395459, "longitude": -75.293563 } } + ] + +} diff --git a/framework/src/onos/tools/test/topos/attmpls.py b/framework/src/onos/tools/test/topos/attmpls.py new file mode 100644 index 00000000..4fe71154 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmpls.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class AttMplsTopo( Topo ): + "Internet Topology Zoo Specimen." + + def __init__( self ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self ) + + # add nodes, switches first... + NY54 = self.addSwitch( 's25' ) # 40.728270, -73.994483 + CMBR = self.addSwitch( 's1' ) # 42.373730, -71.109734 + CHCG = self.addSwitch( 's2', protocols='OpenFlow13' ) # 41.877461, -87.642892 + CLEV = self.addSwitch( 's3' ) # 41.498928, -81.695217 + RLGH = self.addSwitch( 's4' ) # 35.780150, -78.644026 + ATLN = self.addSwitch( 's5' ) # 33.749017, -84.394168 + PHLA = self.addSwitch( 's6' ) # 39.952906, -75.172278 + WASH = self.addSwitch( 's7' ) # 38.906696, -77.035509 + NSVL = self.addSwitch( 's8' ) # 36.166410, -86.787305 + STLS = self.addSwitch( 's9', protocols='OpenFlow13' ) # 38.626418, -90.198143 + NWOR = self.addSwitch( 's10' ) # 29.951475, -90.078434 + HSTN = self.addSwitch( 's11' ) # 29.763249, -95.368332 + SNAN = self.addSwitch( 's12' ) # 29.424331, -98.491745 + DLLS = self.addSwitch( 's13' ) # 32.777665, -96.802064 + ORLD = self.addSwitch( 's14' ) # 28.538641, -81.381110 + DNVR = self.addSwitch( 's15' ) # 39.736623, -104.984887 + KSCY = self.addSwitch( 's16' ) # 39.100725, -94.581228 + SNFN = self.addSwitch( 's17' ) # 37.779751, -122.409791 + SCRM = self.addSwitch( 's18' ) # 38.581001, -121.497844 + PTLD = self.addSwitch( 's19' ) # 45.523317, -122.677768 + STTL = self.addSwitch( 's20' ) # 47.607326, -122.331786 + SLKC = self.addSwitch( 's21' ) # 40.759577, -111.895079 + LA03 = self.addSwitch( 's22', protocols='OpenFlow13' ) # 34.056346, -118.235951 + SNDG = self.addSwitch( 's23' ) # 32.714564, -117.153528 + PHNX = self.addSwitch( 's24' ) # 33.448289, -112.076299 + + # ... and now hosts + NY54_host = self.addHost( 'h25' ) + CMBR_host = self.addHost( 'h1' ) + CHCG_host = self.addHost( 'h2' ) + CLEV_host = self.addHost( 'h3' ) + RLGH_host = self.addHost( 'h4' ) + ATLN_host = self.addHost( 'h5' ) + PHLA_host = self.addHost( 'h6' ) + WASH_host = self.addHost( 'h7' ) + NSVL_host = self.addHost( 'h8' ) + STLS_host = self.addHost( 'h9' ) + NWOR_host = self.addHost( 'h10' ) + HSTN_host = self.addHost( 'h11' ) + SNAN_host = self.addHost( 'h12' ) + DLLS_host = self.addHost( 'h13' ) + ORLD_host = self.addHost( 'h14' ) + DNVR_host = self.addHost( 'h15' ) + KSCY_host = self.addHost( 'h16' ) + SNFN_host = self.addHost( 'h17' ) + SCRM_host = self.addHost( 'h18' ) + PTLD_host = self.addHost( 'h19' ) + STTL_host = self.addHost( 'h20' ) + SLKC_host = self.addHost( 'h21' ) + LA03_host = self.addHost( 'h22' ) + SNDG_host = self.addHost( 'h23' ) + PHNX_host = self.addHost( 'h24' ) + + # add edges between switch and corresponding host + self.addLink( NY54 , NY54_host ) + self.addLink( CMBR , CMBR_host ) + self.addLink( CHCG , CHCG_host ) + self.addLink( CLEV , CLEV_host ) + self.addLink( RLGH , RLGH_host ) + self.addLink( ATLN , ATLN_host ) + self.addLink( PHLA , PHLA_host ) + self.addLink( WASH , WASH_host ) + self.addLink( NSVL , NSVL_host ) + self.addLink( STLS , STLS_host ) + self.addLink( NWOR , NWOR_host ) + self.addLink( HSTN , HSTN_host ) + self.addLink( SNAN , SNAN_host ) + self.addLink( DLLS , DLLS_host ) + self.addLink( ORLD , ORLD_host ) + self.addLink( DNVR , DNVR_host ) + self.addLink( KSCY , KSCY_host ) + self.addLink( SNFN , SNFN_host ) + self.addLink( SCRM , SCRM_host ) + self.addLink( PTLD , PTLD_host ) + self.addLink( STTL , STTL_host ) + self.addLink( SLKC , SLKC_host ) + self.addLink( LA03 , LA03_host ) + self.addLink( SNDG , SNDG_host ) + self.addLink( PHNX , PHNX_host ) + + # add edges between switches + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms') + self.addLink( NY54 , CHCG, bw=10, delay='0.806374975652ms') + self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms') + self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms') + self.addLink( NY54 , WASH, bw=10, delay='0.605826192092ms') + self.addLink( CMBR , PHLA, bw=10, delay='1.4018238197ms') + self.addLink( CHCG , CLEV, bw=10, delay='0.232315346482ms') + self.addLink( CHCG , PHLA, bw=10, delay='1.07297714274ms') + self.addLink( CHCG , STLS, bw=10, delay='1.12827896944ms') + self.addLink( CHCG , DNVR, bw=10, delay='1.35964770335ms') + self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms') + self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms') + self.addLink( CHCG , SNFN, bw=10, delay='0.620743405435ms') + self.addLink( CHCG , STTL, bw=10, delay='0.93027212534ms') + self.addLink( CHCG , SLKC, bw=10, delay='0.735621751348ms') + self.addLink( CLEV , NSVL, bw=10, delay='0.523419372248ms') + self.addLink( CLEV , STLS, bw=10, delay='1.00360290845ms') + self.addLink( CLEV , PHLA, bw=10, delay='0.882912133249ms') + self.addLink( RLGH , ATLN, bw=10, delay='1.1644489729ms') + self.addLink( RLGH , WASH, bw=10, delay='1.48176810502ms') + self.addLink( ATLN , WASH, bw=10, delay='0.557636936322ms') + self.addLink( ATLN , NSVL, bw=10, delay='1.32869749865ms') + self.addLink( ATLN , STLS, bw=10, delay='0.767705554748ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms') + self.addLink( ATLN , ORLD, bw=10, delay='1.46119152532ms') + self.addLink( PHLA , WASH, bw=10, delay='0.372209320106ms') + self.addLink( NSVL , STLS, bw=10, delay='1.43250491305ms') + self.addLink( NSVL , DLLS, bw=10, delay='1.67698215288ms') + self.addLink( STLS , DLLS, bw=10, delay='0.256389964194ms') + self.addLink( STLS , KSCY, bw=10, delay='0.395511571791ms') + self.addLink( STLS , LA03, bw=10, delay='0.257085227363ms') + self.addLink( NWOR , HSTN, bw=10, delay='0.0952906633914ms') + self.addLink( NWOR , DLLS, bw=10, delay='1.60231329739ms') + self.addLink( NWOR , ORLD, bw=10, delay='0.692731063896ms') + self.addLink( HSTN , SNAN, bw=10, delay='0.284150653798ms') + self.addLink( HSTN , DLLS, bw=10, delay='1.65690128332ms') + self.addLink( HSTN , ORLD, bw=10, delay='0.731886304782ms') + self.addLink( SNAN , PHNX, bw=10, delay='1.34258627257ms') + self.addLink( SNAN , DLLS, bw=10, delay='1.50063532341ms') + self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms') + self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms') + self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms') + self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms') + self.addLink( DLLS , SNFN, bw=10, delay='0.74304274592ms') + self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms') + self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms') + self.addLink( DNVR , KSCY, bw=10, delay='0.223328790403ms') + self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms') + self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms') + self.addLink( DNVR , SLKC, bw=10, delay='0.631898982721ms') + self.addLink( KSCY , SNFN, bw=10, delay='0.922778522233ms') + self.addLink( SNFN , SCRM, bw=10, delay='0.630352278097ms') + self.addLink( SNFN , PTLD, bw=10, delay='0.828572513655ms') + self.addLink( SNFN , STTL, bw=10, delay='1.54076081649ms') + self.addLink( SNFN , SLKC, bw=10, delay='0.621507502625ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms') + self.addLink( SCRM , SLKC, bw=10, delay='0.461350343644ms') + self.addLink( PTLD , STTL, bw=10, delay='1.17591515181ms') + self.addLink( SLKC , LA03, bw=10, delay='0.243225267023ms') + self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms') + self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms') + self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms') + self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms') + self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') + +topos = { 'att': ( lambda: AttMplsTopo() ) } diff --git a/framework/src/onos/tools/test/topos/attmplsfast.py b/framework/src/onos/tools/test/topos/attmplsfast.py new file mode 100644 index 00000000..7f904462 --- /dev/null +++ b/framework/src/onos/tools/test/topos/attmplsfast.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class AttMplsTopo( Topo ): + "Internet Topology Zoo Specimen." + + def build( self ): + "Create a topology." + + # add nodes, switches first... + CMBR = self.addSwitch( 's1' ) # 42.373730, -71.109734 + CHCG = self.addSwitch( 's2' ) # 41.877461, -87.642892 + CLEV = self.addSwitch( 's3' ) # 41.498928, -81.695217 + RLGH = self.addSwitch( 's4' ) # 35.780150, -78.644026 + ATLN = self.addSwitch( 's5' ) # 33.749017, -84.394168 + PHLA = self.addSwitch( 's6' ) # 39.952906, -75.172278 + WASH = self.addSwitch( 's7' ) # 38.906696, -77.035509 + NSVL = self.addSwitch( 's8' ) # 36.166410, -86.787305 + STLS = self.addSwitch( 's9' ) # 38.626418, -90.198143 + NWOR = self.addSwitch( 's10' ) # 29.951475, -90.078434 + HSTN = self.addSwitch( 's11' ) # 29.763249, -95.368332 + SNAN = self.addSwitch( 's12' ) # 29.424331, -98.491745 + DLLS = self.addSwitch( 's13' ) # 32.777665, -96.802064 + ORLD = self.addSwitch( 's14' ) # 28.538641, -81.381110 + DNVR = self.addSwitch( 's15' ) # 39.736623, -104.984887 + KSCY = self.addSwitch( 's16' ) # 39.100725, -94.581228 + SNFN = self.addSwitch( 's17' ) # 37.779751, -122.409791 + SCRM = self.addSwitch( 's18' ) # 38.581001, -121.497844 + PTLD = self.addSwitch( 's19' ) # 45.523317, -122.677768 + STTL = self.addSwitch( 's20' ) # 47.607326, -122.331786 + SLKC = self.addSwitch( 's21' ) # 40.759577, -111.895079 + LA03 = self.addSwitch( 's22' ) # 34.056346, -118.235951 + SNDG = self.addSwitch( 's23' ) # 32.714564, -117.153528 + PHNX = self.addSwitch( 's24' ) # 33.448289, -112.076299 + NY54 = self.addSwitch( 's25' ) # 40.728270, -73.994483 + + # ... and now hosts + CMBR_host = self.addHost( 'h1' ) + CHCG_host = self.addHost( 'h2' ) + CLEV_host = self.addHost( 'h3' ) + RLGH_host = self.addHost( 'h4' ) + ATLN_host = self.addHost( 'h5' ) + PHLA_host = self.addHost( 'h6' ) + WASH_host = self.addHost( 'h7' ) + NSVL_host = self.addHost( 'h8' ) + STLS_host = self.addHost( 'h9' ) + NWOR_host = self.addHost( 'h10' ) + HSTN_host = self.addHost( 'h11' ) + SNAN_host = self.addHost( 'h12' ) + DLLS_host = self.addHost( 'h13' ) + ORLD_host = self.addHost( 'h14' ) + DNVR_host = self.addHost( 'h15' ) + KSCY_host = self.addHost( 'h16' ) + SNFN_host = self.addHost( 'h17' ) + SCRM_host = self.addHost( 'h18' ) + PTLD_host = self.addHost( 'h19' ) + STTL_host = self.addHost( 'h20' ) + SLKC_host = self.addHost( 'h21' ) + LA03_host = self.addHost( 'h22' ) + SNDG_host = self.addHost( 'h23' ) + PHNX_host = self.addHost( 'h24' ) + NY54_host = self.addHost( 'h25' ) + + # add edges between switch and corresponding host + self.addLink( NY54 , NY54_host ) + self.addLink( CMBR , CMBR_host ) + self.addLink( CHCG , CHCG_host ) + self.addLink( CLEV , CLEV_host ) + self.addLink( RLGH , RLGH_host ) + self.addLink( ATLN , ATLN_host ) + self.addLink( PHLA , PHLA_host ) + self.addLink( WASH , WASH_host ) + self.addLink( NSVL , NSVL_host ) + self.addLink( STLS , STLS_host ) + self.addLink( NWOR , NWOR_host ) + self.addLink( HSTN , HSTN_host ) + self.addLink( SNAN , SNAN_host ) + self.addLink( DLLS , DLLS_host ) + self.addLink( ORLD , ORLD_host ) + self.addLink( DNVR , DNVR_host ) + self.addLink( KSCY , KSCY_host ) + self.addLink( SNFN , SNFN_host ) + self.addLink( SCRM , SCRM_host ) + self.addLink( PTLD , PTLD_host ) + self.addLink( STTL , STTL_host ) + self.addLink( SLKC , SLKC_host ) + self.addLink( LA03 , LA03_host ) + self.addLink( SNDG , SNDG_host ) + self.addLink( PHNX , PHNX_host ) + + # add edges between switches + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CMBR) + self.addLink( NY54 , CHCG) + self.addLink( NY54 , PHLA) + self.addLink( NY54 , PHLA) + self.addLink( NY54 , WASH) + self.addLink( CMBR , PHLA) + self.addLink( CHCG , CLEV) + self.addLink( CHCG , PHLA) + self.addLink( CHCG , STLS) + self.addLink( CHCG , DNVR) + self.addLink( CHCG , KSCY) + self.addLink( CHCG , KSCY) + self.addLink( CHCG , SNFN) + self.addLink( CHCG , STTL) + self.addLink( CHCG , SLKC) + self.addLink( CLEV , NSVL) + self.addLink( CLEV , STLS) + self.addLink( CLEV , PHLA) + self.addLink( RLGH , ATLN) + self.addLink( RLGH , WASH) + self.addLink( ATLN , WASH) + self.addLink( ATLN , NSVL) + self.addLink( ATLN , STLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , DLLS) + self.addLink( ATLN , ORLD) + self.addLink( PHLA , WASH) + self.addLink( NSVL , STLS) + self.addLink( NSVL , DLLS) + self.addLink( STLS , DLLS) + self.addLink( STLS , KSCY) + self.addLink( STLS , LA03) + self.addLink( NWOR , HSTN) + self.addLink( NWOR , DLLS) + self.addLink( NWOR , ORLD) + self.addLink( HSTN , SNAN) + self.addLink( HSTN , DLLS) + self.addLink( HSTN , ORLD) + self.addLink( SNAN , PHNX) + self.addLink( SNAN , DLLS) + self.addLink( DLLS , DNVR) + self.addLink( DLLS , DNVR) + self.addLink( DLLS , KSCY) + self.addLink( DLLS , KSCY) + self.addLink( DLLS , SNFN) + self.addLink( DLLS , LA03) + self.addLink( DLLS , LA03) + self.addLink( DNVR , KSCY) + self.addLink( DNVR , SNFN) + self.addLink( DNVR , SNFN) + self.addLink( DNVR , SLKC) + self.addLink( KSCY , SNFN) + self.addLink( SNFN , SCRM) + self.addLink( SNFN , PTLD) + self.addLink( SNFN , STTL) + self.addLink( SNFN , SLKC) + self.addLink( SNFN , LA03) + self.addLink( SNFN , LA03) + self.addLink( SNFN , LA03) + self.addLink( SCRM , SLKC) + self.addLink( PTLD , STTL) + self.addLink( SLKC , LA03) + self.addLink( LA03 , SNDG) + self.addLink( LA03 , SNDG) + self.addLink( LA03 , PHNX) + self.addLink( LA03 , PHNX) + self.addLink( SNDG , PHNX) + +topos = { 'att': ( lambda: AttMplsTopo() ) } diff --git a/framework/src/onos/tools/test/topos/chordal.py b/framework/src/onos/tools/test/topos/chordal.py new file mode 100644 index 00000000..22f9ca19 --- /dev/null +++ b/framework/src/onos/tools/test/topos/chordal.py @@ -0,0 +1,402 @@ +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class chordalTopo( Topo ): + + def __init__( self, **opts ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self, **opts ) + + # add nodes, switches first... + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + s8 = self.addSwitch( 's8' ) + s9 = self.addSwitch( 's9' ) + s10 = self.addSwitch( 's10' ) + s11 = self.addSwitch( 's11' ) + s12 = self.addSwitch( 's12' ) + s13 = self.addSwitch( 's13' ) + s14 = self.addSwitch( 's14' ) + s15 = self.addSwitch( 's15' ) + s16 = self.addSwitch( 's16' ) + s17 = self.addSwitch( 's17' ) + s18 = self.addSwitch( 's18' ) + s19 = self.addSwitch( 's19' ) + s20 = self.addSwitch( 's20' ) + s21 = self.addSwitch( 's21' ) + s22 = self.addSwitch( 's22' ) + s23 = self.addSwitch( 's23' ) + s24 = self.addSwitch( 's24' ) + s25 = self.addSwitch( 's25' ) + + # ... and now hosts + s1_host = self.addHost( 'h1' ) + s2_host = self.addHost( 'h2' ) + s3_host = self.addHost( 'h3' ) + s4_host = self.addHost( 'h4' ) + s5_host = self.addHost( 'h5' ) + s6_host = self.addHost( 'h6' ) + s7_host = self.addHost( 'h7' ) + s8_host = self.addHost( 'h8' ) + s9_host = self.addHost( 'h9' ) + s10_host = self.addHost( 'h10' ) + s11_host = self.addHost( 'h11' ) + s12_host = self.addHost( 'h12' ) + s13_host = self.addHost( 'h13' ) + s14_host = self.addHost( 'h14' ) + s15_host = self.addHost( 'h15' ) + s16_host = self.addHost( 'h16' ) + s17_host = self.addHost( 'h17' ) + s18_host = self.addHost( 'h18' ) + s19_host = self.addHost( 'h19' ) + s20_host = self.addHost( 'h20' ) + s21_host = self.addHost( 'h21' ) + s22_host = self.addHost( 'h22' ) + s23_host = self.addHost( 'h23' ) + s24_host = self.addHost( 'h24' ) + s25_host = self.addHost( 'h25' ) + + # add edges between switch and corresponding host + self.addLink( s1 , s1_host ) + self.addLink( s2 , s2_host ) + self.addLink( s3 , s3_host ) + self.addLink( s4 , s4_host ) + self.addLink( s5 , s5_host ) + self.addLink( s6 , s6_host ) + self.addLink( s7 , s7_host ) + self.addLink( s8 , s8_host ) + self.addLink( s9 , s9_host ) + self.addLink( s10 , s10_host ) + self.addLink( s11 , s11_host ) + self.addLink( s12 , s12_host ) + self.addLink( s13 , s13_host ) + self.addLink( s14 , s14_host ) + self.addLink( s15 , s15_host ) + self.addLink( s16 , s16_host ) + self.addLink( s17 , s17_host ) + self.addLink( s18 , s18_host ) + self.addLink( s19 , s19_host ) + self.addLink( s20 , s20_host ) + self.addLink( s21 , s21_host ) + self.addLink( s22 , s22_host ) + self.addLink( s23 , s23_host ) + self.addLink( s24 , s24_host ) + self.addLink( s25 , s25_host ) + self.addLink(s1, s2) + self.addLink(s1, s3) + self.addLink(s1, s4) + self.addLink(s1, s5) + self.addLink(s1, s6) + self.addLink(s1, s7) + self.addLink(s1, s8) + self.addLink(s1, s9) + self.addLink(s1, s10) + self.addLink(s1, s11) + self.addLink(s1, s12) + self.addLink(s1, s13) + self.addLink(s1, s14) + self.addLink(s1, s15) + self.addLink(s1, s16) + self.addLink(s1, s17) + self.addLink(s1, s18) + self.addLink(s1, s19) + self.addLink(s1, s20) + self.addLink(s1, s21) + self.addLink(s1, s22) + self.addLink(s1, s23) + self.addLink(s1, s24) + self.addLink(s1, s25) + self.addLink(s2, s3) + self.addLink(s2, s4) + self.addLink(s2, s5) + self.addLink(s2, s6) + self.addLink(s2, s7) + self.addLink(s2, s8) + self.addLink(s2, s9) + self.addLink(s2, s10) + self.addLink(s2, s11) + self.addLink(s2, s12) + self.addLink(s2, s13) + self.addLink(s2, s14) + self.addLink(s2, s15) + self.addLink(s2, s16) + self.addLink(s2, s17) + self.addLink(s2, s18) + self.addLink(s2, s19) + self.addLink(s2, s20) + self.addLink(s2, s21) + self.addLink(s2, s22) + self.addLink(s2, s23) + self.addLink(s2, s24) + self.addLink(s2, s25) + self.addLink(s3, s4) + self.addLink(s3, s5) + self.addLink(s3, s6) + self.addLink(s3, s7) + self.addLink(s3, s8) + self.addLink(s3, s9) + self.addLink(s3, s10) + self.addLink(s3, s11) + self.addLink(s3, s12) + self.addLink(s3, s13) + self.addLink(s3, s14) + self.addLink(s3, s15) + self.addLink(s3, s16) + self.addLink(s3, s17) + self.addLink(s3, s18) + self.addLink(s3, s19) + self.addLink(s3, s20) + self.addLink(s3, s21) + self.addLink(s3, s22) + self.addLink(s3, s23) + self.addLink(s3, s24) + self.addLink(s3, s25) + self.addLink(s4, s5) + self.addLink(s4, s6) + self.addLink(s4, s7) + self.addLink(s4, s8) + self.addLink(s4, s9) + self.addLink(s4, s10) + self.addLink(s4, s11) + self.addLink(s4, s12) + self.addLink(s4, s13) + self.addLink(s4, s14) + self.addLink(s4, s15) + self.addLink(s4, s16) + self.addLink(s4, s17) + self.addLink(s4, s18) + self.addLink(s4, s19) + self.addLink(s4, s20) + self.addLink(s4, s21) + self.addLink(s4, s22) + self.addLink(s4, s23) + self.addLink(s4, s24) + self.addLink(s4, s25) + self.addLink(s5, s6) + self.addLink(s5, s7) + self.addLink(s5, s8) + self.addLink(s5, s9) + self.addLink(s5, s10) + self.addLink(s5, s11) + self.addLink(s5, s12) + self.addLink(s5, s13) + self.addLink(s5, s14) + self.addLink(s5, s15) + self.addLink(s5, s16) + self.addLink(s5, s17) + self.addLink(s5, s18) + self.addLink(s5, s19) + self.addLink(s5, s20) + self.addLink(s5, s21) + self.addLink(s5, s22) + self.addLink(s5, s23) + self.addLink(s5, s24) + self.addLink(s5, s25) + self.addLink(s6, s7) + self.addLink(s6, s8) + self.addLink(s6, s9) + self.addLink(s6, s10) + self.addLink(s6, s11) + self.addLink(s6, s12) + self.addLink(s6, s13) + self.addLink(s6, s14) + self.addLink(s6, s15) + self.addLink(s6, s16) + self.addLink(s6, s17) + self.addLink(s6, s18) + self.addLink(s6, s19) + self.addLink(s6, s20) + self.addLink(s6, s21) + self.addLink(s6, s22) + self.addLink(s6, s23) + self.addLink(s6, s24) + self.addLink(s6, s25) + self.addLink(s7, s8) + self.addLink(s7, s9) + self.addLink(s7, s10) + self.addLink(s7, s11) + self.addLink(s7, s12) + self.addLink(s7, s13) + self.addLink(s7, s14) + self.addLink(s7, s15) + self.addLink(s7, s16) + self.addLink(s7, s17) + self.addLink(s7, s18) + self.addLink(s7, s19) + self.addLink(s7, s20) + self.addLink(s7, s21) + self.addLink(s7, s22) + self.addLink(s7, s23) + self.addLink(s7, s24) + self.addLink(s7, s25) + self.addLink(s8, s9) + self.addLink(s8, s10) + self.addLink(s8, s11) + self.addLink(s8, s12) + self.addLink(s8, s13) + self.addLink(s8, s14) + self.addLink(s8, s15) + self.addLink(s8, s16) + self.addLink(s8, s17) + self.addLink(s8, s18) + self.addLink(s8, s19) + self.addLink(s8, s20) + self.addLink(s8, s21) + self.addLink(s8, s22) + self.addLink(s8, s23) + self.addLink(s8, s24) + self.addLink(s8, s25) + self.addLink(s9, s10) + self.addLink(s9, s11) + self.addLink(s9, s12) + self.addLink(s9, s13) + self.addLink(s9, s14) + self.addLink(s9, s15) + self.addLink(s9, s16) + self.addLink(s9, s17) + self.addLink(s9, s18) + self.addLink(s9, s19) + self.addLink(s9, s20) + self.addLink(s9, s21) + self.addLink(s9, s22) + self.addLink(s9, s23) + self.addLink(s9, s24) + self.addLink(s9, s25) + self.addLink(s10, s11) + self.addLink(s10, s12) + self.addLink(s10, s13) + self.addLink(s10, s14) + self.addLink(s10, s15) + self.addLink(s10, s16) + self.addLink(s10, s17) + self.addLink(s10, s18) + self.addLink(s10, s19) + self.addLink(s10, s20) + self.addLink(s10, s21) + self.addLink(s10, s22) + self.addLink(s10, s23) + self.addLink(s10, s24) + self.addLink(s10, s25) + self.addLink(s11, s12) + self.addLink(s11, s13) + self.addLink(s11, s14) + self.addLink(s11, s15) + self.addLink(s11, s16) + self.addLink(s11, s17) + self.addLink(s11, s18) + self.addLink(s11, s19) + self.addLink(s11, s20) + self.addLink(s11, s21) + self.addLink(s11, s22) + self.addLink(s11, s23) + self.addLink(s11, s24) + self.addLink(s11, s25) + self.addLink(s12, s13) + self.addLink(s12, s14) + self.addLink(s12, s15) + self.addLink(s12, s16) + self.addLink(s12, s17) + self.addLink(s12, s18) + self.addLink(s12, s19) + self.addLink(s12, s20) + self.addLink(s12, s21) + self.addLink(s12, s22) + self.addLink(s12, s23) + self.addLink(s12, s24) + self.addLink(s12, s25) + self.addLink(s13, s14) + self.addLink(s13, s15) + self.addLink(s13, s16) + self.addLink(s13, s17) + self.addLink(s13, s18) + self.addLink(s13, s19) + self.addLink(s13, s20) + self.addLink(s13, s21) + self.addLink(s13, s22) + self.addLink(s13, s23) + self.addLink(s13, s24) + self.addLink(s13, s25) + self.addLink(s14, s15) + self.addLink(s14, s16) + self.addLink(s14, s17) + self.addLink(s14, s18) + self.addLink(s14, s19) + self.addLink(s14, s20) + self.addLink(s14, s21) + self.addLink(s14, s22) + self.addLink(s14, s23) + self.addLink(s14, s24) + self.addLink(s14, s25) + self.addLink(s15, s16) + self.addLink(s15, s17) + self.addLink(s15, s18) + self.addLink(s15, s19) + self.addLink(s15, s20) + self.addLink(s15, s21) + self.addLink(s15, s22) + self.addLink(s15, s23) + self.addLink(s15, s24) + self.addLink(s15, s25) + self.addLink(s16, s17) + self.addLink(s16, s18) + self.addLink(s16, s19) + self.addLink(s16, s20) + self.addLink(s16, s21) + self.addLink(s16, s22) + self.addLink(s16, s23) + self.addLink(s16, s24) + self.addLink(s16, s25) + self.addLink(s17, s18) + self.addLink(s17, s19) + self.addLink(s17, s20) + self.addLink(s17, s21) + self.addLink(s17, s22) + self.addLink(s17, s23) + self.addLink(s17, s24) + self.addLink(s17, s25) + self.addLink(s18, s19) + self.addLink(s18, s20) + self.addLink(s18, s21) + self.addLink(s18, s22) + self.addLink(s18, s23) + self.addLink(s18, s24) + self.addLink(s18, s25) + self.addLink(s19, s20) + self.addLink(s19, s21) + self.addLink(s19, s22) + self.addLink(s19, s23) + self.addLink(s19, s24) + self.addLink(s19, s25) + self.addLink(s20, s21) + self.addLink(s20, s22) + self.addLink(s20, s23) + self.addLink(s20, s24) + self.addLink(s20, s25) + self.addLink(s21, s22) + self.addLink(s21, s23) + self.addLink(s21, s24) + self.addLink(s21, s25) + self.addLink(s22, s23) + self.addLink(s22, s24) + self.addLink(s22, s25) + self.addLink(s23, s24) + self.addLink(s23, s25) + self.addLink(s24, s25) + +topos = { 'chordal': ( lambda: chordalTopo() ) } diff --git a/framework/src/onos/tools/test/topos/cord.json b/framework/src/onos/tools/test/topos/cord.json new file mode 100644 index 00000000..418a6b4b --- /dev/null +++ b/framework/src/onos/tools/test/topos/cord.json @@ -0,0 +1,24 @@ +{ + "devices": [ + { "uri": "of:00010001e88b9368", "mac": "0001e88b9368", "annotations": { "name": "s101", "latitude": 37.710742, "longitude": -103.975010 }}, + { "uri": "of:00010001e88b939b", "mac": "0001e88b939b", "annotations": { "name": "s102", "latitude": 37.756072, "longitude": -97.547678 }}, + { "uri": "of:00010001e88b938c", "mac": "0001e88b938c", "annotations": { "name": "s103", "latitude": 37.657851, "longitude": -90.778101 }}, + { "uri": "of:00010001e88b93ad", "mac": "0001e88b93ad", "annotations": { "name": "s104", "latitude": 37.634692, "longitude": -84.215821 }}, + { "uri": "of:00010001e88b93bc", "mac": "0001e88b93bc", "annotations": { "name": "s105", "latitude": 41.951018, "longitude": -103.853350 }}, + { "uri": "of:00010001e88b93c2", "mac": "0001e88b93c2", "annotations": { "name": "s106", "latitude": 41.945684, "longitude": -97.526174 }}, + { "uri": "of:00010001e88b9398", "mac": "0001e88b9398", "annotations": { "name": "s107", "latitude": 41.952876, "longitude": -90.696484 }}, + { "uri": "of:00010001e88b27e3", "mac": "0001e88b27e3", "annotations": { "name": "s108", "latitude": 41.996877, "longitude": -84.169273 }} + ], + "hosts": [ + { "id": "00:1f:29:e1:2c:36/-1", "mac": "00:1f:29:e1:2c:36", "vlan": -1, "location": "of:00010001e88b9368/46", "ip": "10.200.1.11", "annotations": { "name": "h11", "latitude": 34.384830, "longitude": -104.019262 }}, + { "id": "00:1e:0b:cb:9d:64/-1", "mac": "00:1e:0b:cb:9d:64", "vlan": -1, "location": "of:00010001e88b9368/45", "ip": "10.200.1.12", "annotations": { "name": "h12", "latitude": 34.384830, "longitude": -104.019262 }}, + { "id": "00:1c:c4:6b:d8:12/-1", "mac": "00:1c:c4:6b:d8:12", "vlan": -1, "location": "of:00010001e88b939b/46", "ip": "10.200.2.21", "annotations": { "name": "h21", "latitude": 34.133376, "longitude": -89.442032 }}, + { "id": "00:1e:0b:ca:90:44/-1", "mac": "00:1e:0b:ca:90:44", "vlan": -1, "location": "of:00010001e88b939b/45", "ip": "10.200.2.22", "annotations": { "name": "h22", "latitude": 34.133376, "longitude": -89.442032 }}, + { "id": "00:1e:0b:ca:e5:1a/-1", "mac": "00:1e:0b:ca:e5:1a", "vlan": -1, "location": "of:00010001e88b938c/46", "ip": "10.200.3.31", "annotations": { "name": "h31", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "2c:44:fd:e0:90:40/-1", "mac": "2c:44:fd:e0:90:40", "vlan": -1, "location": "of:00010001e88b938c/45", "ip": "10.200.3.32", "annotations": { "name": "h32", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "2c:44:fd:e0:90:44/-1", "mac": "2c:44:fd:e0:90:44", "vlan": -1, "location": "of:00010001e88b938c/47", "ip": "10.200.3.33", "annotations": { "name": "h33", "latitude": 34.166625, "longitude": -91.983293 }}, + { "id": "00:1e:0b:cb:3f:ac/-1", "mac": "00:1e:0b:cb:3f:ac", "vlan": -1, "location": "of:00010001e88b93ad/46", "ip": "10.200.4.41", "annotations": { "name": "h41", "latitude": 34.225065, "longitude": -97.492882 }}, + { "id": "c8:1f:66:e2:9b:d0/-1", "mac": "c8:1f:66:e2:9b:d0", "vlan": -1, "location": "of:00010001e88b93ad/45", "ip": "10.200.4.42", "annotations": { "name": "h42", "latitude": 34.249236, "longitude": -84.253025 }}, + { "id": "c8:1f:66:e2:9b:d2/-1", "mac": "c8:1f:66:e2:9b:d2", "vlan": -1, "location": "of:00010001e88b93ad/47", "ip": "10.200.4.43", "annotations": { "name": "h43", "latitude": 34.249236, "longitude": -84.253025 }} + ] +} diff --git a/framework/src/onos/tools/test/topos/fractal.py b/framework/src/onos/tools/test/topos/fractal.py new file mode 100755 index 00000000..bc5c6899 --- /dev/null +++ b/framework/src/onos/tools/test/topos/fractal.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +from mininet.topo import Topo + +class FractalTopo( Topo ): + def build( self, n=3, h=2 ): + + clusters = [] + for i in range( 1, n+1 ): + clusterSws = [] + # create switches in cluster + for j in range( 1, n+1 ): + id = i * 1000 + j + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + [ self.addLink(s, sw) for s in clusterSws ] + clusterSws.append(sw) + clusters.append(clusterSws) + + for i in range( 1, n+1 ): + # create the edge switch + id = i * 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + for j in range( 1, h+1 ): + id = i * 1000 + j + host = self.addHost( 'h%d' % id ) + self.addLink( host, sw ) + + for i in range( 1, n+1 ): + # connect the clusters + if i == n: + id = n * 1000000 + 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + self.addLink(clusters[0].pop(0), sw) + + else: + id = (i+1) * 1000000 + i * 10000 + sw = self.addSwitch('s%d' % id, dpid=str(id).zfill(16)) + self.addLink(clusters[i-1].pop(0), sw) + self.addLink(clusters[i].pop(0), sw) + + +topos = { 'fractal': FractalTopo } + +def run(): + topo = FractalTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() + diff --git a/framework/src/onos/tools/test/topos/linear-2.json b/framework/src/onos/tools/test/topos/linear-2.json new file mode 100644 index 00000000..c248a236 --- /dev/null +++ b/framework/src/onos/tools/test/topos/linear-2.json @@ -0,0 +1,6 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "annotations": { "driver": "ovs-corsa" } }, + { "alias": "s2", "uri": "of:0000000000000002", "annotations": { "driver": "ovs-corsa" } } + ] +} diff --git a/framework/src/onos/tools/test/topos/newFuncTopo.py b/framework/src/onos/tools/test/topos/newFuncTopo.py new file mode 100644 index 00000000..5edf7f78 --- /dev/null +++ b/framework/src/onos/tools/test/topos/newFuncTopo.py @@ -0,0 +1,148 @@ +#!/usr/bin/python + +""" +Custom topology for Mininet +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import Host, RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections +from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch ) + +class VLANHost( Host ): + def config( self, vlan=100, **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ifconfig %s inet 0' % intf ) + self.cmd( 'vconfig add %s %d' % ( intf, vlan ) ) + self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) ) + newName = '%s.%d' % ( intf, vlan ) + intf.name = newName + self.nameToIntf[ newName ] = intf + return r + +class IPv6Host( Host ): + def config( self, v6Addr='1000:1/64', **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ifconfig %s inet 0' % intf ) + self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) ) + return r + +class dualStackHost( Host ): + def config( self, v6Addr='2000:1/64', **params ): + r = super( Host, self ).config( **params ) + intf = self.defaultIntf() + self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) ) + return r + +class MyTopo( Topo ): + + def __init__( self ): + # Initialize topology + Topo.__init__( self ) + # Switch S5 Hosts + host1=self.addHost( 'h1', ip='10.1.0.2/24' ) + host2=self.addHost( 'h2', cls=IPv6Host, v6Addr='1000::2/64' ) + host3=self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='2000::2/64' ) + #VLAN hosts + host4=self.addHost( 'h4', ip='100.1.0.2/24', cls=VLANHost, vlan=100 ) + host5=self.addHost( 'h5', ip='200.1.0.2/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host6=self.addHost( 'h6', ip='11.1.0.2/24' ) + host7=self.addHost( 'h7', ip='12.1.0.2/24' ) + #Multicast Sender + host8=self.addHost( 'h8', ip='10.1.0.4/24' ) + + # Switch S6 Hosts + host9=self.addHost( 'h9', ip='10.1.0.5/24' ) + host10=self.addHost( 'h10', cls=IPv6Host, v6Addr='1000::3/64' ) + host11=self.addHost( 'h11', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='2000::3/64' ) + #VLAN hosts + host12=self.addHost( 'h12', ip='100.1.0.3/24', cls=VLANHost, vlan=100 ) + host13=self.addHost( 'h13', ip='200.1.0.3/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host14=self.addHost( 'h14', ip='11.1.0.3/24' ) + host15=self.addHost( 'h15', ip='12.1.0.3/24' ) + #Multicast Receiver + host16=self.addHost( 'h16', ip='10.1.0.7/24' ) + + # Switch S7 Hosts + host17=self.addHost( 'h17', ip='10.1.0.8/24' ) + host18=self.addHost( 'h18', cls=IPv6Host, v6Addr='1000::4/64' ) + host19=self.addHost( 'h19', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='2000::4/64' ) + #VLAN hosts + host20=self.addHost( 'h20', ip='100.1.0.4/24', cls=VLANHost, vlan=100 ) + host21=self.addHost( 'h21', ip='200.1.0.4/24', cls=VLANHost, vlan=200 ) + #VPN-1 and VPN-2 Hosts + host22=self.addHost( 'h22', ip='11.1.0.4/24' ) + host23=self.addHost( 'h23', ip='12.1.0.4/24' ) + #Multicast Receiver + host24=self.addHost( 'h24', ip='10.1.0.10/24' ) + + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + + self.addLink(s5,host1) + self.addLink(s5,host2) + self.addLink(s5,host3) + self.addLink(s5,host4) + self.addLink(s5,host5) + self.addLink(s5,host6) + self.addLink(s5,host7) + self.addLink(s5,host8) + + self.addLink(s6,host9) + self.addLink(s6,host10) + self.addLink(s6,host11) + self.addLink(s6,host12) + self.addLink(s6,host13) + self.addLink(s6,host14) + self.addLink(s6,host15) + self.addLink(s6,host16) + + self.addLink(s7,host17) + self.addLink(s7,host18) + self.addLink(s7,host19) + self.addLink(s7,host20) + self.addLink(s7,host21) + self.addLink(s7,host22) + self.addLink(s7,host23) + self.addLink(s7,host24) + + self.addLink(s1,s2) + self.addLink(s1,s3) + self.addLink(s1,s4) + self.addLink(s1,s5) + self.addLink(s2,s3) + self.addLink(s2,s5) + self.addLink(s2,s6) + self.addLink(s3,s4) + self.addLink(s3,s6) + self.addLink(s4,s7) + topos = { 'mytopo': ( lambda: MyTopo() ) } + +# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS + +def setupNetwork(): + "Create network" + topo = MyTopo() + network = Mininet(topo=topo, autoSetMacs=True, controller=None) + network.start() + CLI( network ) + network.stop() + +if __name__ == '__main__': + setLogLevel('info') + #setLogLevel('debug') + setupNetwork() diff --git a/framework/src/onos/tools/test/topos/obelisk.py b/framework/src/onos/tools/test/topos/obelisk.py new file mode 100755 index 00000000..fb6ccdbe --- /dev/null +++ b/framework/src/onos/tools/test/topos/obelisk.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +from mininet.topo import Topo + +class ObeliskTopo( Topo ): + def __init__( self ): + Topo.__init__( self ) + topSwitch = self.addSwitch('s1',dpid='1000'.zfill(16)) + leftTopSwitch = self.addSwitch('s2',dpid='2000'.zfill(16)) + rightTopSwitch = self.addSwitch('s5',dpid='5000'.zfill(16)) + leftBotSwitch = self.addSwitch('s3',dpid='3000'.zfill(16)) + rightBotSwitch = self.addSwitch('s6',dpid='6000'.zfill(16)) + midBotSwitch = self.addSwitch('s28',dpid='2800'.zfill(16)) + + topHost = self.addHost( 'h1' ) + leftTopHost = self.addHost('h2') + rightTopHost = self.addHost('h5') + leftBotHost = self.addHost('h3') + rightBotHost = self.addHost('h6') + midBotHost = self.addHost('h28') + self.addLink(topSwitch,topHost) + self.addLink(leftTopSwitch,leftTopHost) + self.addLink(rightTopSwitch,rightTopHost) + self.addLink(leftBotSwitch,leftBotHost) + self.addLink(rightBotSwitch,rightBotHost) + self.addLink(midBotSwitch,midBotHost) + self.addLink(leftTopSwitch,rightTopSwitch) + self.addLink(topSwitch,leftTopSwitch) + self.addLink(topSwitch,rightTopSwitch) + self.addLink(leftTopSwitch,leftBotSwitch) + self.addLink(rightTopSwitch,rightBotSwitch) + self.addLink(leftBotSwitch,midBotSwitch) + self.addLink(midBotSwitch,rightBotSwitch) + + agg1Switch = self.addSwitch('s4',dpid = '3004'.zfill(16)) + agg2Switch = self.addSwitch('s7',dpid = '6007'.zfill(16)) + agg1Host = self.addHost('h4') + agg2Host = self.addHost('h7') + self.addLink(agg1Switch,agg1Host) + self.addLink(agg2Switch,agg2Host) + self.addLink(agg1Switch, leftBotSwitch) + self.addLink(agg2Switch, rightBotSwitch) + + for i in range(10): + num = str(i+8) + switch = self.addSwitch('s'+num,dpid = ('30'+num.zfill(2)).zfill(16)) + host = self.addHost('h'+num) + self.addLink(switch, host) + self.addLink(switch, agg1Switch) + + for i in range(10): + num = str(i+18) + switch = self.addSwitch('s'+num,dpid = ('60'+num.zfill(2)).zfill(16)) + host = self.addHost('h'+num) + self.addLink(switch, host) + self.addLink(switch, agg2Switch) + +topos = { 'obelisk': (lambda: ObeliskTopo() ) } + +def run(): + topo = ObeliskTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() + diff --git a/framework/src/onos/tools/test/topos/obeliskHostCheck.py b/framework/src/onos/tools/test/topos/obeliskHostCheck.py new file mode 100755 index 00000000..e928f89f --- /dev/null +++ b/framework/src/onos/tools/test/topos/obeliskHostCheck.py @@ -0,0 +1,91 @@ +#!/usr/bin/python + +import sys +import os +import json + +# TODO: if none given, use OCI +try: + onosIp = sys.argv[1] + print "Reading hosts view from ONOS node " + onosIp + ":" +except Exception as e: + print "Error reading ONOS IP arguement" + print e +# Grab the json objects from ONOS +output = os.popen("onos " + onosIp + " \"hosts -j\"" ) +hosts = json.loads( output.read() ) +#hosts = json.loads( output.split( 'Logging in as karaf\n' )[1] ) + +hostAttachment = True +# FIXME: topo-HA/obelisk specific mappings: +# key is mac and value is dpid +mappings = {} +for i in range( 1, 29 ): # hosts 1 through 28 + # set up correct variables: + macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2) + if i == 1: + deviceId = "1000".zfill(16) + elif i == 2: + deviceId = "2000".zfill(16) + elif i == 3: + deviceId = "3000".zfill(16) + elif i == 4: + deviceId = "3004".zfill(16) + elif i == 5: + deviceId = "5000".zfill(16) + elif i == 6: + deviceId = "6000".zfill(16) + elif i == 7: + deviceId = "6007".zfill(16) + elif i >= 8 and i <= 17: + dpid = '3' + str( i ).zfill( 3 ) + deviceId = dpid.zfill(16) + elif i >= 18 and i <= 27: + dpid = '6' + str( i ).zfill( 3 ) + deviceId = dpid.zfill(16) + elif i == 28: + deviceId = "2800".zfill(16) + mappings[ macId ] = deviceId + +if hosts or "Error" not in hosts: + if hosts == []: + print "WARNING: There are no hosts discovered" + else: + for host in hosts: + mac = None + location = None + device = None + port = None + try: + mac = host.get( 'mac' ) + assert mac, "mac field could not be found for this host object" + + location = host.get( 'location' ) + assert location, "location field could not be found for this host object" + + # Trim the protocol identifier off deviceId + device = str( location.get( 'elementId' ) ).split(':')[1] + assert device, "elementId field could not be found for this host location object" + + port = location.get( 'port' ) + assert port, "port field could not be found for this host location object" + + # Now check if this matches where they should be + if mac and device and port: + if device != mappings[ str( mac ) ]: + print "The attachment device is incorrect for host " + str( mac ) +\ + ". Expected: " + mappings[ str( mac ) ] + "; Actual: " + device + hostAttachment = False + if str( port ) != "1": + print "The attachment port is incorrect for host " + str( mac ) +\ + ". Expected: 1; Actual: " + str( port) + hostAttachment = False + else: + hostAttachment = False + except AssertionError as e: + print "ERROR: Json object not as expected:" + print e + print "host object: " + repr( host ) + hostAttachment = False +else: + print "No hosts json output or \"Error\" in output. hosts = " + repr( hosts ) diff --git a/framework/src/onos/tools/test/topos/oe-linear-3.json b/framework/src/onos/tools/test/topos/oe-linear-3.json new file mode 100644 index 00000000..44fccd99 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-linear-3.json @@ -0,0 +1,48 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM1", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, { "port": 20, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM2", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 11, "speed": 100000, "type": "FIBER" }, { "port": 21, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM3", "latitude": 33.9, "longitude": -118.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER1", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER2", "latitude": 37.3, "longitude": -121.9 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + ], + + "links" : [ + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff03/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff02/21", "dst": "of:0000ffffffffff03/31", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } } + ], + + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000ffffffff0001/1", "ip": "10.0.0.1" }, + { "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000ffffffff0002/1", "ip": "10.0.0.2" } + ] +}
\ No newline at end of file diff --git a/framework/src/onos/tools/test/topos/oe-nonlinear-10.json b/framework/src/onos/tools/test/topos/oe-nonlinear-10.json new file mode 100644 index 00000000..9bf291e8 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-nonlinear-10.json @@ -0,0 +1,149 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SFO-W10", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed":100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SJC-W10", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 20, "speed": 100000, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "LAX-W10", "latitude": 33.9, "longitude": -118.4, "optical.regens": 0 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff04", "mac": "ffffffffffff04", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "SDG-W10", "latitude": 32.8, "longitude": -117.1, "optical.regens": 3 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, + { "port":50, "speed": 0, "type": "FIBER" }, + { "port":20, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff05", "mac": "ffffffffffff05", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "MSP-M10", "latitude": 44.8, "longitude": -93.1, "optical.regens": 3 }, + "ports": [ { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 40, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff06", "mac": "ffffffffffff06", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "DFW-M10", "latitude": 32.8, "longitude": -97.1, "optical.regens": 3 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 40, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff07", "mac": "ffffffffffff07", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "CHG-N10", "latitude": 41.8, "longitude": -87.6, "optical.regens": 3 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff08", "mac": "ffffffffffff08", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "IAD-M10", "latitude": 38.8, "longitude": -77.1, "optical.regens": 3 }, + "ports": [ { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 30, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff09", "mac": "ffffffffffff09", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "JFK-M10", "latitude": 40.8, "longitude": -73.1, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffffff0A", "mac": "ffffffffffff0A", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ATL-S10", "latitude": 33.8, "longitude": -84.1, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 0, "type": "FIBER" }, + { "port": 20, "speed": 0, "type": "FIBER" }, + { "port": 50, "speed": 0, "type": "FIBER" }] + }, + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "SFO-R10", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0003", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "LAX-R10", "latitude": 33.9, "longitude": -118.4 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0003", "mac": "ffffffffff0004", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "SDG-R10", "latitude": 32.8, "longitude": -117.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0004", "mac": "ffffffffff0007", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "CHG-R10", "latitude": 41.8, "longitude": -87.6 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0005", "mac": "ffffffffff0009", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "JFK-R10", "latitude": 40.8, "longitude": -73.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0006", "mac": "ffffffffff000A", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ATL-R10", "latitude": 33.8, "longitude": -84.1 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + + ], + + "links" : [ + { "src": "of:0000ffffffffff01/50", "dst": "of:0000ffffffffff02/30","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 48, "durable": "true" } }, + { "src": "of:0000ffffffffff02/50", "dst": "of:0000ffffffffff03/30","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 493, "durable": "true" } }, + { "src": "of:0000ffffffffff03/50", "dst": "of:0000ffffffffff04/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 171, "durable": "true" } }, + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff05/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2555, "durable": "true" } }, + { "src": "of:0000ffffffffff02/20", "dst": "of:0000ffffffffff05/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2539, "durable": "true" } }, + { "src": "of:0000ffffffffff03/20", "dst": "of:0000ffffffffff06/50","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1979, "durable": "true" } }, + { "src": "of:0000ffffffffff04/20", "dst": "of:0000ffffffffff06/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1867, "durable": "true" } }, + { "src": "of:0000ffffffffff05/30", "dst": "of:0000ffffffffff06/40","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1378, "durable": "true" } }, + { "src": "of:0000ffffffffff05/40", "dst": "of:0000ffffffffff07/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 2200, "durable": "true" } }, + { "src": "of:0000ffffffffff06/30", "dst": "of:0000ffffffffff08/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1918, "durable": "true" } }, + { "src": "of:0000ffffffffff07/20", "dst": "of:0000ffffffffff08/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 3625, "durable": "true" } }, + { "src": "of:0000ffffffffff07/30", "dst": "of:0000ffffffffff09/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 3880, "durable": "true" } }, + { "src": "of:0000ffffffffff08/20", "dst": "of:0000ffffffffff0A/50", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 838, "durable": "true" } }, + { "src": "of:0000ffffffffff09/20", "dst": "of:0000ffffffffff0A/20","type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1245, "durable": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff04/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0003/2", "dst": "of:0000ffffffffff06/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0004/2", "dst": "of:0000ffffffffff07/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0005/2", "dst": "of:0000ffffffffff09/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } }, + { "src": "of:0000ffffffff0006/2", "dst": "of:0000ffffffffff0A/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" } } + ] +} diff --git a/framework/src/onos/tools/test/topos/oe-nonlinear-4.json b/framework/src/onos/tools/test/topos/oe-nonlinear-4.json new file mode 100644 index 00000000..47782a86 --- /dev/null +++ b/framework/src/onos/tools/test/topos/oe-nonlinear-4.json @@ -0,0 +1,52 @@ +{ + "devices" : [ + { + "uri": "of:0000ffffffffff01", "mac": "ffffffffffff01", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM1", "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 }, + "ports": [ { "port": 10, "speed": 100000, "type": "FIBER" }, { "port": 20, "speed": 0, "type": "FIBER" }, { "port": 22, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff02", "mac": "ffffffffffff02", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM2", "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 }, + "ports": [ { "port": 11, "speed": 100000, "type": "FIBER" }, { "port": 21, "speed": 0, "type": "FIBER" }, { "port": 22, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff03", "mac": "ffffffffffff03", "type": "ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM3", "latitude": 33.9, "longitude": -118.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffffff04", "mac": "ffffffffffff04", "type":"ROADM", + "mfr": "Linc", "hw": "OE", "sw": "?", "serial": "?", + "annotations": { "name": "ROADM4", "latitude": 39.9, "longitude": -119.4, "optical.regens": 2 }, + "ports": [ { "port": 30, "speed": 0, "type": "FIBER" }, { "port": 31, "speed": 0, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0001", "mac": "ffffffffff0001", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER1", "latitude": 37.6, "longitude": -122.3 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + }, + { + "uri": "of:0000ffffffff0002", "mac": "ffffffffff0002", "type": "SWITCH", + "mfr": "Linc", "hw": "PK", "sw": "?", "serial": "?", + "annotations": { "name": "ROUTER2", "latitude": 37.3, "longitude": -121.9 }, + "ports": [ { "port": 1, "speed": 10000, "type": "COPPER" }, { "port": 2, "speed": 100000, "type": "FIBER" } ] + } + ], + + "links" : [ + { "src": "of:0000ffffffffff01/20", "dst": "of:0000ffffffffff03/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff02/21", "dst": "of:0000ffffffffff03/31", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff01/22", "dst": "of:0000ffffffffff04/30", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffffff04/31", "dst": "of:0000ffffffffff02/22", "type": "OPTICAL", "annotations": { "optical.waves": 80, "optical.type": "WDM", "durable": "true", "inactive": "true" } }, + + { "src": "of:0000ffffffff0001/2", "dst": "of:0000ffffffffff01/10", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } }, + { "src": "of:0000ffffffff0002/2", "dst": "of:0000ffffffffff02/11", "type": "OPTICAL", "annotations": { "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true", "inactive": "true" } } + ] + +} + diff --git a/framework/src/onos/tools/test/topos/onos.py b/framework/src/onos/tools/test/topos/onos.py new file mode 100755 index 00000000..3e5bff7c --- /dev/null +++ b/framework/src/onos/tools/test/topos/onos.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python + +# TODO add onos-app-fwd to features +# TODO check if service is running... i think this might already be done by mn + +from mininet.node import Controller, OVSSwitch, CPULimitedHost, RemoteController +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.topo import LinearTopo, Topo +from mininet.log import setLogLevel, info, warn +from mininet.util import quietRun, numCores + +from shutil import copyfile +from os import environ, path +from functools import partial +import time +from sys import argv +from time import sleep +from sets import Set + +class ONOS( Controller ): + "TODO" + + onosDir = '/opt/onos/' + + def __init__( self, name, onosDir=onosDir, + reactive=True, features=[ 'onos-app-tvue' ], + **kwargs ): + '''TODO''' + + Controller.__init__( self, name, **kwargs ) + # the following have been done for us: + #self.ip = ip ('127.0.0.1') + #self.port = port (6633) + #self.protocol = protocol ('tcp') + #self.checkListening() + + self.onosDir = onosDir + self.karafDir = onosDir + 'apache-karaf-3.0.3/' + self.instanceDir = self.karafDir + + # add default modules + # TODO: consider an ordered set + self.features = Set([ 'webconsole', + 'onos-rest', + 'onos-api', + 'onos-cli', + 'onos-openflow' ]) + self.features.update( features ) + # add reactive forwarding modules + if reactive: + self.features.update( ['onos-app-fwd', + 'onos-app-proxyarp', + 'onos-app-mobility' ] ) + # add the distributed core if we are in a namespace with no trivial core + if self.inNamespace and 'onos-core-trivial' not in self.features: + self.features.add( 'onos-core' ) + # if there is no core, add the trivial one + if 'onos-core' not in self.features: + self.features.add( 'onos-core-trivial' ) + print self.features + + def start( self ): + if self.inNamespace: + instanceOpts = ( '-furl mvn:org.onosproject/onos-features/1.3.0-SNAPSHOT/xml/features ' + '-s 8101' ) + if self.ip is not None: + instanceOpts += (' -a %s' % self.IP() ) + self.userCmd( self.karafDir + 'bin/instance create %s %s' % ( instanceOpts, self.name ) ) + self.instanceDir = self.karafDir + 'instances/%s/' % self.name + else: + # we are running in the root namespace, so let's use the root instance + # clean up the data directory + #self.userCmd( 'rm -rf '+ self.karafDir + 'data/' ) + pass + + self.userCmd( 'rm -rf '+ self.instanceDir + 'data/' ) + + # Update etc/org.apache.karaf.features.cfg + self.updateFeatures() + + # TODO 2. Update etc/hazelcast.xml : interface lines + #cp etc/hazelcast.xml instances/c1/etc/ + self.updateHazelcast() + + # TODO 3. Update etc/system.properties : onos.ip + # TODO 4. Update config/cluster.json : with all nodes + + # start onos + self.userCmd( '%sbin/instance start -d %s' % ( self.karafDir, self.name ) ) + #TODO we should wait for startup... + + def stop( self ): + self.userCmd( self.instanceDir + 'bin/stop' ) + #if self.inNamespace: + # self.userCmd( self.karafDir + 'bin/instance destroy %s' % self.name ) + self.terminate() + + def updateHazelcast( self ): + hz = '192.168.123.*' + if self.ip is not None: + hz = '.'.join(self.ip.split('.')[:-1]) + '.*' + + readfile = self.karafDir + 'etc/hazelcast.xml' + writefile = self.instanceDir + 'etc/hazelcast.xml' + with open( readfile, 'r' ) as r: + with open( writefile, 'w' ) as w: + for line in r.readlines(): + if '<interface>' in line: + line = '<interface>' + hz + '</interface>\n' + w.write( line ) + + def updateFeatures( self ): + filename = self.instanceDir + 'etc/org.apache.karaf.features.cfg' + with open( filename, 'r+' ) as f: + lines = f.readlines() + f.seek(0) + f.truncate() + for line in lines: + #print '?', line, + if 'featuresBoot=' in line: + # parse the features from the line + features = line.rstrip().split('=')[1].split(',') + # add the features to our features set + self.features.update( features ) + # generate the new features line + line = 'featuresBoot=' + ','.join( self.features ) + '\n' + #print '!', line, + f.write( line ) + + + @classmethod + def isAvailable( self ): + return quietRun( 'ls %s' % self.onosDir ) + + def userCmd( self, cmd ): + # switch to the non-root user because karaf gets upset otherwise + # because the .m2repo is not stored with root + cmd = 'sudo -u %s %s' % ( self.findUser(), cmd ) + return self.cmd( cmd ) + + @staticmethod + def findUser(): + "Try to return logged-in (usually non-root) user" + try: + # If we're running sudo + return os.environ[ 'SUDO_USER' ] + except: + try: + # Logged-in user (if we have a tty) + return quietRun( 'who am i' ).split()[ 0 ] + except: + # Give up and return effective user + return quietRun( 'whoami' ) + + +class ControlNetwork( Topo ): + "Control Network Topology" + def __init__( self, n, dataController=ONOS, **kwargs ): + """n: number of data network controller nodes + dataController: class for data network controllers""" + Topo.__init__( self, **kwargs ) + # Connect everything to a single switch + cs0 = self.addSwitch( 'cs0' ) + # Add hosts which will serve as data network controllers + for i in range( 1, n+1 ): + c = self.addHost( 'c%s' % i, cls=dataController, + inNamespace=True ) + self.addLink( c, cs0 ) + # Connect switch to root namespace so that data network + # switches will be able to talk to us + root = self.addHost( 'root', inNamespace=False ) + self.addLink( root, cs0 ) + +class ONOSCluster( Controller ): + # TODO + n = 3 + + def start( self ): + ctopo = ControlNetwork( n=self.n, dataController=ONOS ) + self.cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None ) + self.cnet.addController( 'cc0', controller=Controller ) + self.cnet.start() + + self.ctrls = [] + for host in self.cnet.hosts: + if isinstance( host, Controller ): + self.ctrls.append( host ) + host.start() + + def stop( self ): + for host in self.cnet.hosts: + if isinstance( host, Controller ): + host.stop() + self.cnet.stop() + + def clist( self ): + "Return list of Controller proxies for this ONOS cluster" + print 'controllers:', self.ctrls + return self.ctrls + +class OVSSwitchONOS( OVSSwitch ): + "OVS switch which connects to multiple controllers" + def start( self, controllers ): + assert len( controllers ) == 1 + c0 = controllers[ 0 ] + assert type( c0 ) == ONOSCluster + controllers = c0.clist() + OVSSwitch.start( self, controllers ) + +controllers = { 'onos': ONOS } +switches = { 'ovso': OVSSwitchONOS } + +if __name__ == '__main__': + # Simple test for ONOS() controller class + setLogLevel( 'info' ) #TODO info + size = 2 if len( argv ) != 2 else int( argv[ 1 ] ) + net = Mininet( topo=LinearTopo( size ), + #controller=ONOS, + controller=partial( ONOSCluster, n=3 ), #TODO + switch=OVSSwitchONOS ) + net.start() + #waitConnected( net.switches ) + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/optical.py b/framework/src/onos/tools/test/topos/optical.py new file mode 100755 index 00000000..300332aa --- /dev/null +++ b/framework/src/onos/tools/test/topos/optical.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +''' file: optical.py ''' + +from mininet.topo import Topo +from mininet.node import RemoteController +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info +from mininet.link import Intf, Link +from mininet.util import irange + +class NullIntf( Intf ): + "A dummy interface with a blank name that doesn't do any configuration" + def __init__( self, name, **params ): + self.name = '' + +class NullLink( Link ): + "A dummy link that doesn't touch either interface" + def makeIntfPair( cls, intf1, intf2, addr1=None, addr2=None ): + pass + def delete( self ): + pass + +class OpticalTopo( Topo ): + + def addIntf( self, switch, intfName ): + "Add intf intfName to switch" + self.addLink( switch, switch, cls=NullLink, + intfName1=intfName, cls2=NullIntf, intfName2=intfName ) + + def build( self, n=2, tapStart=3 ): + + # Add hosts and switches + hosts = [] + switches = [] + for i in irange( 1, n ): + h = self.addHost( 'h%d' % i ) + s = self.addSwitch( 's%d' % i, dpid="0000ffffffff%04d" % i ) + self.addLink( h, s ) + hosts.append( h ) + switches.append( s ) + + # Add optical tap interfaces + tapNum = tapStart + for sw in switches: + self.addIntf( sw, 'tap%d' % tapNum ) + tapNum += 1 + +# if you use, sudo mn --custom custom/optical.py, then register the topo: +#sudo mn --custom optical.py --topo optical,5 +topos = { 'optical': OpticalTopo } + +def installStaticFlows( net ): + for sw in net.switches: + info( 'Adding flows to %s...' % sw.name ) + sw.dpctl( 'add-flow', 'in_port=1,actions=output=2' ) + sw.dpctl( 'add-flow', 'in_port=2,actions=output=1' ) + info( sw.dpctl( 'dump-flows' ) ) + +def run( n ): + topo = OpticalTopo( n ) + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + #installStaticFlows( net ) + CLI( net ) + net.stop() + +# if the script is run directly (sudo custom/optical.py): +if __name__ == '__main__': + import sys + try: + n = int( sys.argv[1] ) + except: + print ( 'Usage: ./optical.py n # n is number of switches\n' + 'Starting with default of 2 switches...\n' ) + n = 2 + setLogLevel( 'info' ) + run( n ) diff --git a/framework/src/onos/tools/test/topos/optical2.py b/framework/src/onos/tools/test/topos/optical2.py new file mode 100644 index 00000000..36cdbadd --- /dev/null +++ b/framework/src/onos/tools/test/topos/optical2.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +''' file: custom/optical.py ''' + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info +from mininet.link import Intf, Link +from mininet.node import RemoteController + +class NullIntf( Intf ): + "A dummy interface with a blank name that doesn't do any configuration" + def __init__( self, name, **params ): + self.name = '' + +class NullLink( Link ): + "A dummy link that doesn't touch either interface" + def makeIntfPair( cls, intf1, intf2, *args, **kwargs ): + pass + def delete( self ): + pass + +class OpticalTopo(Topo): + def addIntf( self, switch, intfName ): + "Add intf intfName to switch" + self.addLink( switch, switch, cls=NullLink, + intfName1=intfName, cls2=NullIntf ) + def __init__(self): + + # Initialize topology + Topo.__init__(self) + + # Add hosts and switches + h1 = self.addHost('h1') + h2 = self.addHost('h2') + h3 = self.addHost('h3') + h4 = self.addHost('h4') + h5 = self.addHost('h5') + h6 = self.addHost('h6') + + s1 = self.addSwitch('s1', dpid="0000ffffffff0001") + s2 = self.addSwitch('s2', dpid="0000ffffffff0002") + s3 = self.addSwitch('s3', dpid="0000ffffffff0003") + s4 = self.addSwitch('s4', dpid="0000ffffffff0004") + s5 = self.addSwitch('s5', dpid="0000ffffffff0005") + s6 = self.addSwitch('s6', dpid="0000ffffffff0006") + + + # Add links from hosts to OVS + self.addLink(s1, h1) + self.addLink(s2, h2) + self.addLink(s3, h3) + self.addLink(s4, h4) + self.addLink(s5, h5) + self.addLink(s6, h6) + + # add links from ovs to linc-oe + # sorry about the syntax :( + self.addIntf(s1,'tap29') + self.addIntf(s2,'tap30') + self.addIntf(s3,'tap31') + self.addIntf(s4,'tap32') + self.addIntf(s5,'tap33') + self.addIntf(s6,'tap34') + + # if you use, sudo mn --custom custom/optical.py, then register the topo: +topos = {'optical': ( lambda: OpticalTopo() )} + + +def run(): + c = RemoteController('c','127.0.0.1',6633) + net = Mininet( topo=OpticalTopo(),controller=None,autoSetMacs=True) + net.addController(c) + net.start() + + #installStaticFlows( net ) + CLI( net ) + net.stop() + +# if the script is run directly (sudo custom/optical.py): +if __name__ == '__main__': + setLogLevel('info') + run() diff --git a/framework/src/onos/tools/test/topos/opticalTest.py b/framework/src/onos/tools/test/topos/opticalTest.py new file mode 100644 index 00000000..b34f08da --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalTest.py @@ -0,0 +1,98 @@ +#!/usr/bin/python + +from opticalUtils import MininetOE, LINCSwitch, LINCLink +from mininet.topo import Topo +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.cli import CLI + +class SmallOpticalTopo( Topo ): + + def build( self ): + o1ann = { "latitude": 37.6, "longitude": -122.3, "optical.regens": 0 } + O1 = self.addSwitch( 'SFO-W10', dpid='0000ffffffffff01', annotations=o1ann, cls=LINCSwitch ) + o2ann = { "latitude": 37.3, "longitude": -121.9, "optical.regens": 0 } + O2 = self.addSwitch( 'SJC-W10', dpid='0000ffffffffff02', annotations=o2ann, cls=LINCSwitch ) + o3ann = { "latitude": 33.9, "longitude": -118.4, "optical.regens": 0 } + O3 = self.addSwitch( 'LAX-W10', dpid='0000ffffffffff03', annotations=o3ann, cls=LINCSwitch ) + o4ann = { "latitude": 32.8, "longitude": -117.1, "optical.regens": 3 } + O4 = self.addSwitch( 'SDG-W10', dpid='0000ffffffffff04', annotations=o4ann, cls=LINCSwitch ) + o5ann = { "latitude": 44.8, "longitude": -93.1, "optical.regens": 3 } + O5 = self.addSwitch( 'MSP-M10', dpid='0000ffffffffff05', annotations=o5ann, cls=LINCSwitch ) + o6ann = { "latitude": 32.8, "longitude": -97.1, "optical.regens": 3 } + O6 = self.addSwitch( 'DFW-M10', dpid='0000ffffffffff06', annotations=o6ann, cls=LINCSwitch ) + o7ann = { "latitude": 41.8, "longitude": -87.6, "optical.regens": 3 } + O7 = self.addSwitch( 'CHG-N10', dpid='0000ffffffffff07', annotations=o7ann, cls=LINCSwitch ) + o8ann = { "latitude": 38.8, "longitude": -77.1, "optical.regens": 3 } + O8 = self.addSwitch( 'IAD-M10', dpid='0000ffffffffff08', annotations=o8ann, cls=LINCSwitch ) + o9ann = { "latitude": 40.8, "longitude": -73.1, "optical.regens": 0 } + O9 = self.addSwitch( 'JFK-M10', dpid='0000ffffffffff09', annotations=o9ann, cls=LINCSwitch ) + o10ann = { "latitude": 33.8, "longitude": -84.1, "optical.regens": 0 } + O10 = self.addSwitch( 'ATL-S10', dpid='0000ffffffffff0a', annotations=o10ann, cls=LINCSwitch ) + + + SFOR10 = self.addSwitch( 'SFO-R10', dpid='0000ffffffff0001', annotations={"latitude": 37.6, "longitude": -122.3} ) + LAXR10 = self.addSwitch( 'LAX-R10', dpid='0000ffffffff0002', annotations={ "latitude": 33.9, "longitude": -118.4 } ) + SDGR10 = self.addSwitch( 'SDG-R10', dpid='0000ffffffff0003', annotations={ "latitude": 32.8, "longitude": -117.1 } ) + CHGR10 = self.addSwitch( 'CHG-R10', dpid='0000ffffffff0004', annotations={ "latitude": 41.8, "longitude": -87.6 } ) + JFKR10 = self.addSwitch( 'JFK-R10', dpid='0000ffffffff0005', annotations={ "latitude": 40.8, "longitude": -73.1 } ) + ATLR10 = self.addSwitch( 'ATL-R10', dpid='0000ffffffff0006', annotations={ "latitude": 33.8, "longitude": -84.1 } ) + + self.addLink( O1, O2, port1=50, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O2, O3, port1=50, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O3, O4, port1=50, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O1, O5, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O2, O5, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O3, O6, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O4, O6, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O5, O6, port1=30, port2=40, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O5, O7, port1=40, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O6, O8, port1=30, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O7, O8, port1=20, port2=30, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O7, O9, port1=30, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O8, O10, port1=20, port2=50, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + self.addLink( O9, O10, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) + + self.addLink( SFOR10, O1, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SFOR10, O1, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( LAXR10, O3, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + # added second tap + self.addLink( LAXR10, O3, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SDGR10, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( CHGR10, O7, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( JFKR10, O9, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( JFKR10, O9, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + self.addLink( ATLR10, O10, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + h1 = self.addHost( 'h1' ) + h2 = self.addHost( 'h2' ) + h3 = self.addHost( 'h3' ) + h4 = self.addHost( 'h4' ) + h5 = self.addHost( 'h5' ) + h6 = self.addHost( 'h6' ) + + self.addLink( SFOR10, h1, port1=1 ) + self.addLink( LAXR10, h2, port1=1 ) + self.addLink( SDGR10, h3, port1=1 ) + self.addLink( CHGR10, h4, port1=1 ) + self.addLink( JFKR10, h5, port1=1 ) + self.addLink( ATLR10, h6, port1=1 ) + +if __name__ == '__main__': + import sys + if len( sys.argv ) >= 2: + controllers = sys.argv[1:] + else: + print 'Usage:sudo -E python opticalTest.py (<Controller IP>)+' + print 'Using localhost...\n' + controllers = [ '127.0.0.1' ] + + setLogLevel( 'info' ) + net = MininetOE( topo=SmallOpticalTopo(), controller=None, autoSetMacs=True ) + net.addControllers( controllers ) + net.start() + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/opticalTestBig.py b/framework/src/onos/tools/test/topos/opticalTestBig.py new file mode 100644 index 00000000..943699b0 --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalTestBig.py @@ -0,0 +1,391 @@ +#!/usr/bin/python + +from opticalUtils import MininetOE, LINCSwitch, LINCLink +from mininet.topo import Topo +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.cli import CLI + +class BigOpticalTopo( Topo ): + + def build( self ): + # Optical layer ROADMs + o1ann = { "latitude": 32.508086, "longitude": -99.741564, "optical.regens": 0 } + O1 = self.addSwitch( 'ABLNTXRO', dpid='0000ffffffffff01', annotations=o1ann, cls=LINCSwitch ) + o2ann = { "latitude": 35.084446, "longitude": -106.649719, "optical.regens": 0 } + O2 = self.addSwitch( 'ALBQNMMA', dpid='0000ffffffffff02', annotations=o2ann, cls=LINCSwitch ) + o3ann = { "latitude": 42.652222, "longitude": -73.758333, "optical.regens": 0 } + O3 = self.addSwitch( 'ALBYNYSS', dpid='0000ffffffffff03', annotations=o3ann, cls=LINCSwitch ) + o4ann = { "latitude": 33.755833, "longitude": -97.743057, "optical.regens": 5 } + O4 = self.addSwitch( 'ATLNGATL', dpid='0000ffffffffff04', annotations=o4ann, cls=LINCSwitch ) # ATLNGATL Connected to packet node + o5ann = { "latitude": 42.882778, "longitude": -78.877778, "optical.regens": 0 } + O5 = self.addSwitch( 'BFLONYFR', dpid='0000ffffffffff05', annotations=o5ann, cls=LINCSwitch ) + o6ann = { "latitude": 45.781667, "longitude": -108.509167, "optical.regens": 0 } + O6 = self.addSwitch( 'BLNGMTMA', dpid='0000ffffffffff06', annotations=o6ann, cls=LINCSwitch ) + o7ann = { "latitude": 39.293781, "longitude": -76.614127, "optical.regens": 0 } + O7 = self.addSwitch( 'BLTMMDCH', dpid='0000ffffffffff07', annotations=o7ann, cls=LINCSwitch ) + o8ann = { "latitude": 33.517223, "longitude": -86.812225, "optical.regens": 0 } + O8 = self.addSwitch( 'BRHMALMT', dpid='0000ffffffffff08', annotations=o8ann, cls=LINCSwitch ) + o9ann = { "latitude": 46.836379, "longitude": -100.796917, "optical.regens": 0 } + O9 = self.addSwitch( 'BSMRNDJC', dpid='0000ffffffffff09', annotations=o9ann, cls=LINCSwitch ) + o10ann = { "latitude": 30.449722, "longitude": -91.184167, "optical.regens": 0 } + O10 = self.addSwitch( 'BTRGLAMA', dpid='0000ffffffffff0a', annotations=o10ann, cls=LINCSwitch ) + o11ann = { "latitude": 41.881484, "longitude": -87.640432, "optical.regens": 4 } + O11 = self.addSwitch( 'CHCGILCL', dpid='0000ffffffffff0b', annotations=o11ann, cls=LINCSwitch ) + o12ann = { "latitude": 35.224924, "longitude": -80.837502, "optical.regens": 0 } + O12 = self.addSwitch( 'CHRLNCCA', dpid='0000ffffffffff0c', annotations=o12ann, cls=LINCSwitch ) + o13ann = { "latitude": 32.785278, "longitude": -79.938056, "optical.regens": 0 } + O13 = self.addSwitch( 'CHTNSCDT', dpid='0000ffffffffff0d', annotations=o13ann, cls=LINCSwitch ) + o14ann = { "latitude": 41.498333, "longitude": -81.686943, "optical.regens": 0 } + O14 = self.addSwitch( 'CLEVOH02', dpid='0000ffffffffff0e', annotations=o14ann, cls=LINCSwitch ) + o15ann = { "latitude": 39.965279, "longitude": -82.996666, "optical.regens": 0 } + O15 = self.addSwitch( 'CLMBOH11', dpid='0000ffffffffff0f', annotations=o15ann, cls=LINCSwitch ) + o16ann = { "latitude": 42.36745, "longitude": -71.084918, "optical.regens": 0 } + O16 = self.addSwitch( 'CMBRMA01', dpid='0000ffffffffff10', annotations=o16ann, cls=LINCSwitch ) + o17ann = { "latitude": 39.102778, "longitude": -84.516944, "optical.regens": 0 } + O17 = self.addSwitch( 'CNCNOHWS', dpid='0000ffffffffff11', annotations=o17ann, cls=LINCSwitch ) + o18ann = { "latitude": 32.797524, "longitude": -96.780431, "optical.regens": 0 } + O18 = self.addSwitch( 'DLLSTXTL', dpid='0000ffffffffff12', annotations=o18ann, cls=LINCSwitch ) # DLLSTXTL Connected to packet node + o19ann = { "latitude": 39.744999, "longitude": -104.996391, "optical.regens": 0 } + O19 = self.addSwitch( 'DNVRCOMA', dpid='0000ffffffffff13', annotations=o19ann, cls=LINCSwitch ) + o20ann = { "latitude": 42.332779, "longitude": -83.054169, "optical.regens": 5 } + O20 = self.addSwitch( 'DTRTMIBA', dpid='0000ffffffffff14', annotations=o20ann, cls=LINCSwitch ) + o21ann = { "latitude": 31.756389, "longitude": -106.483611, "optical.regens": 0 } + O21 = self.addSwitch( 'ELPSTXMA', dpid='0000ffffffffff15', annotations=o21ann, cls=LINCSwitch ) + o22ann = { "latitude": 36.73923, "longitude": -119.79423, "optical.regens": 0 } + O22 = self.addSwitch( 'FRSNCA01', dpid='0000ffffffffff16', annotations=o22ann, cls=LINCSwitch ) + o23ann = { "latitude": 36.072222, "longitude": -79.793889, "optical.regens": 0 } + O23 = self.addSwitch( 'GNBONCEU', dpid='0000ffffffffff17', annotations=o23ann, cls=LINCSwitch ) + o24ann = { "latitude": 41.765833, "longitude": -72.676389, "optical.regens": 0 } + O24 = self.addSwitch( 'HRFRCT03', dpid='0000ffffffffff18', annotations=o24ann, cls=LINCSwitch ) + o25ann = { "latitude": 29.748333, "longitude": -95.36528, "optical.regens": 0 } + O25 = self.addSwitch( 'HSTNTX01', dpid='0000ffffffffff19', annotations=o25ann, cls=LINCSwitch ) + o26ann = { "latitude": 30.33071, "longitude": -81.43, "optical.regens": 0 } + O26 = self.addSwitch( 'JCVLFLCL', dpid='0000ffffffffff1a', annotations=o26ann, cls=LINCSwitch ) + o27ann = { "latitude": 39.096649, "longitude": -94.578716, "optical.regens": 0 } + O27 = self.addSwitch( 'KSCYMO09', dpid='0000ffffffffff1b', annotations=o27ann, cls=LINCSwitch ) + o28ann = { "latitude": 40.5899999,"longitude": -73.6699993, "optical.regens": 0 } + O28 = self.addSwitch( 'LGISLAND', dpid='0000ffffffffff1c', annotations=o28ann, cls=LINCSwitch ) + o29ann = { "latitude": 34.051227, "longitude": -118.252958, "optical.regens": 0 } + O29 = self.addSwitch( 'LSANCA03', dpid='0000ffffffffff1d', annotations=o29ann, cls=LINCSwitch ) # LSANCA03 Connected to packet node + o30ann = { "latitude": 36.168056, "longitude": -115.138889, "optical.regens": 0 } + O30 = self.addSwitch( 'LSVGNV02', dpid='0000ffffffffff1e', annotations=o30ann, cls=LINCSwitch ) + o31ann = { "latitude":38.249167, "longitude": -85.760833, "optical.regens": 0 } + O31 = self.addSwitch( 'LSVLKYCS', dpid='0000ffffffffff1f', annotations=o31ann, cls=LINCSwitch ) + o32ann = { "latitude": 34.740833, "longitude": -92.271942, "optical.regens": 2 } + O32 = self.addSwitch( 'LTRKARFR', dpid='0000ffffffffff20', annotations=o32ann, cls=LINCSwitch ) + o33ann = { "latitude": 25.779167, "longitude": -80.195, "optical.regens": 0 } + O33 = self.addSwitch( 'MIAMFLAC', dpid='0000ffffffffff21', annotations=o33ann, cls=LINCSwitch ) + o34ann = { "latitude": 43.037224, "longitude": -87.922501, "optical.regens": 0 } + O34 = self.addSwitch( 'MILWWIHE', dpid='0000ffffffffff22', annotations=o34ann, cls=LINCSwitch ) + o35ann = { "latitude": 35.145158, "longitude": -90.048058, "optical.regens": 0 } + O35 = self.addSwitch( 'MMPHTNMA', dpid='0000ffffffffff23', annotations=o35ann, cls=LINCSwitch ) + o36ann = { "latitude": 44.977365, "longitude": -93.26718, "optical.regens": 0 } + O36 = self.addSwitch( 'MPLSMNDT', dpid='0000ffffffffff24', annotations=o36ann, cls=LINCSwitch ) # MPLSMNDT Connected to packet node + o37ann = { "latitude": 36.853333, "longitude": -76.29, "optical.regens": 0 } + O37 = self.addSwitch( 'NRFLVABS', dpid='0000ffffffffff25', annotations=o37ann, cls=LINCSwitch ) + o38ann = { "latitude": 36.163955, "longitude": -86.775558, "optical.regens": 0 } + O38 = self.addSwitch( 'NSVLTNMT', dpid='0000ffffffffff26', annotations=o38ann, cls=LINCSwitch ) + o39ann = { "latitude": 29.949806, "longitude": -90.07222, "optical.regens": 0 } + O39 = self.addSwitch( 'NWORLAMA', dpid='0000ffffffffff27', annotations=o39ann, cls=LINCSwitch ) + o40ann = { "latitude": 40.734408, "longitude": -74.177978, "optical.regens": 0 } + O40 = self.addSwitch( 'NWRKNJ02', dpid='0000ffffffffff28', annotations=o40ann, cls=LINCSwitch ) # NWRKNJ02 Connected to packet node + o41ann = { "latitude": 40.767497, "longitude": -73.989713, "optical.regens": 0 } + O41 = self.addSwitch( 'NYCMNY54', dpid='0000ffffffffff29', annotations=o41ann, cls=LINCSwitch ) + o42ann = { "latitude": 35.470833, "longitude": -97.515274, "optical.regens": 0 } + O42 = self.addSwitch( 'OKCYOKCE', dpid='0000ffffffffff2a', annotations=o42ann, cls=LINCSwitch ) + o43ann = { "latitude": 37.805556, "longitude": -122.268889, "optical.regens": 2 } + O43 = self.addSwitch( 'OKLDCA03', dpid='0000ffffffffff2b', annotations=o43ann, cls=LINCSwitch ) + o44ann = { "latitude": 41.259167, "longitude":-95.940277, "optical.regens": 0 } + O44 = self.addSwitch( 'OMAHNENW', dpid='0000ffffffffff2c', annotations=o44ann, cls=LINCSwitch ) + o45ann = { "latitude": 28.543279, "longitude": -81.377502, "optical.regens": 0 } + O45 = self.addSwitch( 'ORLDFLMA', dpid='0000ffffffffff2d', annotations=o45ann, cls=LINCSwitch ) # ORLDFLMA Connected to packet node + o46ann = { "latitude": 39.946446, "longitude": -75.184139, "optical.regens": 0 } + O46 = self.addSwitch( 'PHLAPASL', dpid='0000ffffffffff2e', annotations=o46ann, cls=LINCSwitch ) + o47ann = { "latitude": 33.450361, "longitude": -112.07709, "optical.regens": 0 } + O47 = self.addSwitch( 'PHNXAZMA', dpid='0000ffffffffff2f', annotations=o47ann, cls=LINCSwitch ) # PHNXAZMA Connected to packet node + o48ann = { "latitude":40.441387, "longitude": -79.995552, "optical.regens": 0 } + O48 = self.addSwitch( 'PITBPADG', dpid='0000ffffffffff30', annotations=o48ann, cls=LINCSwitch ) + o49ann = { "latitude":41.818889, "longitude": -71.415278, "optical.regens": 0 } + O49 = self.addSwitch( 'PRVDRIGR', dpid='0000ffffffffff31', annotations=o49ann, cls=LINCSwitch ) + o50ann = { "latitude": 45.522499, "longitude": -122.678055, "optical.regens": 2 } + O50 = self.addSwitch( 'PTLDOR62', dpid='0000ffffffffff32', annotations=o50ann, cls=LINCSwitch ) + o51ann = { "latitude": 37.540752, "longitude": -77.436096, "optical.regens": 0 } + O51 = self.addSwitch( 'RCMDVAGR', dpid='0000ffffffffff33', annotations=o51ann, cls=LINCSwitch ) + o52ann = { "latitude": 35.779656, "longitude": -78.640831, "optical.regens": 0 } + O52 = self.addSwitch( 'RLGHNCMO', dpid='0000ffffffffff34', annotations=o52ann, cls=LINCSwitch ) + o53ann = { "latitude": 43.157222, "longitude": -77.616389, "optical.regens": 0 } + O53 = self.addSwitch( 'ROCHNYXA', dpid='0000ffffffffff35', annotations=o53ann, cls=LINCSwitch ) # ROCHNYXA Connected to packet node + o54ann = { "latitude": 38.578609, "longitude": -121.487221, "optical.regens": 0 } + O54 = self.addSwitch( 'SCRMCA01', dpid='0000ffffffffff36', annotations=o54ann, cls=LINCSwitch ) + o55ann = { "latitude": 41.415278, "longitude": -75.649167, "optical.regens": 0 } + O55 = self.addSwitch( 'SCTNPA01', dpid='0000ffffffffff37', annotations=o55ann, cls=LINCSwitch ) + o56ann = { "latitude": 40.767776, "longitude": -111.888336, "optical.regens": 0 } + O56 = self.addSwitch( 'SLKCUTMA', dpid='0000ffffffffff38', annotations=o56ann, cls=LINCSwitch ) + o57ann = { "latitude": 29.429445, "longitude": -98.488892, "optical.regens": 0 } + O57 = self.addSwitch( 'SNANTXCA', dpid='0000ffffffffff39', annotations=o57ann, cls=LINCSwitch ) # SNANTXCA Connected to packet node + o58ann = { "latitude": 34.418889, "longitude": -119.7, "optical.regens": 0 } + O58 = self.addSwitch( 'SNBBCA01', dpid='0000ffffffffff3a', annotations=o58ann, cls=LINCSwitch ) + o59ann = { "latitude":32.746944, "longitude": -117.158611, "optical.regens": 0 } + O59 = self.addSwitch( 'SNDGCA02', dpid='0000ffffffffff3b', annotations=o59ann, cls=LINCSwitch ) + o60ann = { "latitude":37.785143, "longitude": -122.397263, "optical.regens": 0 } + O60 = self.addSwitch( 'SNFCCA21', dpid='0000ffffffffff3c', annotations=o60ann, cls=LINCSwitch ) + o61ann = { "latitude": 37.333333, "longitude": -121.892778, "optical.regens": 0 } + O61 = self.addSwitch( 'SNJSCA02', dpid='0000ffffffffff3d', annotations=o61ann, cls=LINCSwitch ) # SNJSCA02 Connected to packet node + o62ann = { "latitude": 39.795278, "longitude": -89.649444, "optical.regens": 0 } + O62 = self.addSwitch( 'SPFDILSD', dpid='0000ffffffffff3e', annotations=o62ann, cls=LINCSwitch ) + o63ann = { "latitude": 47.654724, "longitude": -117.419167, "optical.regens": 0 } + O63 = self.addSwitch( 'SPKNWA01', dpid='0000ffffffffff3f', annotations=o63ann, cls=LINCSwitch ) + o64ann = { "latitude": 38.633335, "longitude": -90.215279, "optical.regens": 0 } + O64 = self.addSwitch( 'STLSMO09', dpid='0000ffffffffff40', annotations=o64ann, cls=LINCSwitch ) + o65ann = { "latitude": 47.606945, "longitude": -122.333336, "optical.regens": 0 } + O65 = self.addSwitch( 'STTLWA06', dpid='0000ffffffffff41', annotations=o65ann, cls=LINCSwitch ) + o66ann = { "latitude": 43.049444, "longitude": -76.1475, "optical.regens": 3 } + O66 = self.addSwitch( 'SYRCNYSU', dpid='0000ffffffffff42', annotations=o66ann, cls=LINCSwitch ) + o67ann = { "latitude": 28.0225, "longitude": -82.522778, "optical.regens": 0 } + O67 = self.addSwitch( 'TAMQFLFN', dpid='0000ffffffffff43', annotations=o67ann, cls=LINCSwitch ) + o68ann = { "latitude": 32.224444, "longitude": -110.968333, "optical.regens": 0 } + O68 = self.addSwitch( 'TCSNAZMA', dpid='0000ffffffffff44', annotations=o68ann, cls=LINCSwitch ) + o69ann = { "latitude": 30.456389, "longitude": -84.290833, "optical.regens": 0 } + O69 = self.addSwitch( 'TLHSFLAT', dpid='0000ffffffffff45', annotations=o69ann, cls=LINCSwitch ) + o70ann = { "latitude": 41.65, "longitude": -83.538056, "optical.regens": 2 } + O70 = self.addSwitch( 'TOLDOH21', dpid='0000ffffffffff46', annotations=o70ann, cls=LINCSwitch ) + o71ann = { "latitude": 36.151669, "longitude": -95.985832, "optical.regens": 0 } + O71 = self.addSwitch( 'TULSOKTB', dpid='0000ffffffffff47', annotations=o71ann, cls=LINCSwitch ) + o72ann = { "latitude": 38.88306 , "longitude": -77.01028, "optical.regens": 0 } + O72 = self.addSwitch( 'WASHDCSW', dpid='0000ffffffffff48', annotations=o72ann, cls=LINCSwitch ) # WASHDCSW Connected to packet node + o73ann = { "latitude": 39.739167, "longitude": -75.553889, "optical.regens": 0 } + O73 = self.addSwitch( 'WLMGDE01', dpid='0000ffffffffff49', annotations=o73ann, cls=LINCSwitch ) + o74ann = { "latitude": 26.709391, "longitude": -80.05278, "optical.regens": 0 } + O74 = self.addSwitch( 'WPBHFLAN', dpid='0000ffffffffff4a', annotations=o74ann, cls=LINCSwitch ) + o75ann = { "latitude": 29.57, "longitude": -96.7, "optical.regens": 0 } + O75 = self.addSwitch( 'AUSTTXGR', dpid='0000ffffffffff4b', annotations=o75ann, cls=LINCSwitch ) + #o25ann = { "latitude": 29.748333, "longitude": -95.36528, "optical.regens": 0 } + #o57ann = { "latitude": 29.429445, "longitude": -98.488892, "optical.regens": 0 } + + + # Packet Layer switches + ''' # from opticalTest.py + SFOR10 = self.addSwitch( 'SFO-R10', dpid='0000ffffffff0001', annotations={"latitude": 37.6, "longitude": -122.3} ) + LAXR10 = self.addSwitch( 'LAX-R10', dpid='0000ffffffff0002', annotations={ "latitude": 33.9, "longitude": -118.4 } ) + SDGR10 = self.addSwitch( 'SDG-R10', dpid='0000ffffffff0003', annotations={ "latitude": 32.8, "longitude": -117.1 } ) + CHGR10 = self.addSwitch( 'CHG-R10', dpid='0000ffffffff0004', annotations={ "latitude": 41.8, "longitude": -87.6 } ) + JFKR10 = self.addSwitch( 'JFK-R10', dpid='0000ffffffff0005', annotations={ "latitude": 40.8, "longitude": -73.1 } ) + ATLR10 = self.addSwitch( 'ATL-R10', dpid='0000ffffffff0006', annotations={ "latitude": 33.8, "longitude": -84.1 } ) + ''' + WASHDCSWR = self.addSwitch( 'WASHDCSW-R', dpid='0000ffffff000001', annotations={ "latitude": 38.8, "longitude": -77.0 } ) # this switch is O72 + SNJSCA02R = self.addSwitch( 'SNJSCA02-R', dpid='0000ffffff000002', annotations={ "latitude": 37.3, "longitude": -121.8 } ) # O61 + SNANTXCAR = self.addSwitch( 'SNANTXCA-R', dpid='0000ffffff000003', annotations={ "latitude": 29.4, "longitude": -98.4 } ) # O57 + ROCHNYXAR = self.addSwitch( 'ROCHNYXA-R', dpid='0000ffffff000004', annotations={ "latitude": 43.1, "longitude": -77.6 } ) # O53 + PHNXAZMAR = self.addSwitch( 'PHNXAZMA-R', dpid='0000ffffff000005', annotations={ "latitude": 33.4, "longitude": -112.0 } ) # O47 + ORLDFLMAR = self.addSwitch( 'ORLDFLMA-R', dpid='0000ffffff000006', annotations={ "latitude": 28.5, "longitude": -81.3 } ) # O45 + NWRKNJ02R = self.addSwitch( 'NWRKNJ02-R', dpid='0000ffffff000007', annotations={ "latitude": 40.7, "longitude": -74.1 } ) # O40 + MPLSMNDTR = self.addSwitch( 'MPLSMNDT-R', dpid='0000ffffff000008', annotations={ "latitude": 44.9, "longitude": -93.2 } ) # O36 + LSANCA03R = self.addSwitch( 'LSANCA03-R', dpid='0000ffffff000009', annotations={ "latitude": 34.1, "longitude": -118.3 } ) # O29 + DLLSTXTLR = self.addSwitch( 'DLLSTXTL-R', dpid='0000ffffff00000a', annotations={ "latitude": 32.7, "longitude": -96.7 } ) # O18 + ATLNGATLR = self.addSwitch( 'ATLNGATL-R', dpid='0000ffffff00000b', annotations={ "latitude": 33.7, "longitude": -97.7 } ) # O4 + + + + # Optical Links between the ROADMs (although Distance is not used; we should keep these for future reference) + self.addLink( O1, O18, port1=100, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 334, "durable": "true" }, cls=LINCLink ) # ABLNTXRO DLLSTXTL + self.addLink( O1, O21, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 768, "durable": "true" }, cls=LINCLink ) # ABLNTXRO ELPSTXMA + self.addLink( O3, O16, port1=100, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 265, "durable": "true" }, cls=LINCLink ) # ALBYNYSS CMBRMA01 + self.addLink( O3, O66, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 239, "durable": "true" }, cls=LINCLink ) # ALBYNYSS SYRCNYSU + self.addLink( O2, O18, port1=100, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1134, "durable": "true" }, cls=LINCLink ) # ALBQNMMA DLLSTXTL + self.addLink( O2, O19, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 646, "durable": "true" }, cls=LINCLink ) # ALBQNMMA DNVRCOMA + self.addLink( O2, O21, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 444, "durable": "true" }, cls=LINCLink ) # ALBQNMMA ELPSTXMA + self.addLink( O2, O30, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 931, "durable": "true" }, cls=LINCLink ) # ALBQNMMA LSVGNV02 + self.addLink( O4, O8, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 271, "durable": "true" }, cls=LINCLink ) # ATLNGATL BRHMALMT + self.addLink( O4, O12, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 436, "durable": "true" }, cls=LINCLink ) # ATLNGATL CHRLNCCA + self.addLink( O4, O26, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 566, "durable": "true" }, cls=LINCLink ) # ATLNGATL JCVLFLCL + self.addLink( O75, O25, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 283, "durable": "true" }, cls=LINCLink ) # AUSTTXGR HSTNTX01 + self.addLink( O75, O57, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 141, "durable": "true" }, cls=LINCLink ) # AUSTTXGR SNANTXCA + self.addLink( O7, O46, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 170, "durable": "true" }, cls=LINCLink ) # BLTMMDCH PHLAPASL + self.addLink( O7, O48, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 378, "durable": "true" }, cls=LINCLink ) # BLTMMDCH PITBPADG + self.addLink( O7, O70, port1=103, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 68, "durable": "true" }, cls=LINCLink ) # BLTMMDCH WASHDCSW + self.addLink( O10, O25, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 491, "durable": "true" }, cls=LINCLink ) # BTRGLAMA HSTNTX01 + self.addLink( O10, O39, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 144, "durable": "true" }, cls=LINCLink ) # BTRGLAMA NWORLAMA + self.addLink( O6, O9, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 724, "durable": "true" }, cls=LINCLink ) # BLNGMTMA BSMRNDJC + self.addLink( O6, O19, port1=102, port2=107, annotations={ "optical.wves": 80, "optical.type": "WDM", "optical.kms": 875, "durable": "true" }, cls=LINCLink ) # BLNGMTMA DNVRCOMA + self.addLink( O6, O63, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 852, "durable": "true" }, cls=LINCLink ) # BLNGMTMA SPKNWA01 + self.addLink( O8, O38, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 353, "durable": "true" }, cls=LINCLink ) # BRHMALMT NSVLTNMT + self.addLink( O8, O39, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 602, "durable": "true" }, cls=LINCLink ) # BRHMALMT NWORLAMA + self.addLink( O9, O36, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 741, "durable": "true" }, cls=LINCLink ) # BSMRNDJC MPLSMNDT + self.addLink( O16, O49, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 80, "durable": "true" }, cls=LINCLink ) # CMBRMA01 PRVDRIGR + self.addLink( O5, O14, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 333, "durable": "true" }, cls=LINCLink ) # BFLONYFR CLEVOH02 + self.addLink( O5, O53, port1=104, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 128, "durable": "true" }, cls=LINCLink ) # BFLONYFR ROCHNYXA + self.addLink( O13, O26, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 368, "durable": "true" }, cls=LINCLink ) # CHTNSCDT JCVLFLCL + self.addLink( O13, O52, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 424, "durable": "true" }, cls=LINCLink ) # CHTNSCDT RLGHNCMO + self.addLink( O12, O23, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 160, "durable": "true" }, cls=LINCLink ) # CHRLNCCA GNBONCEU + self.addLink( O11, O20, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 458, "durable": "true" }, cls=LINCLink ) # CHCGILCL DTRTMIBA + self.addLink( O11, O34, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 156, "durable": "true" }, cls=LINCLink ) # CHCGILCL MILWWIHE + self.addLink( O11, O62, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 344, "durable": "true" }, cls=LINCLink ) # CHCGILCL SPFDILSD + self.addLink( O17, O15, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 194, "durable": "true" }, cls=LINCLink ) # CNCNOHWS CLMBOH11 + self.addLink( O17, O31, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 172, "durable": "true" }, cls=LINCLink ) # CNCNOHWS LSVLKYCS + self.addLink( O17, O72, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 779, "durable": "true" }, cls=LINCLink ) # CNCNOHWS WASHDCSW + self.addLink( O14, O15, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 243, "durable": "true" }, cls=LINCLink ) # CLEVOH02 CLMBOH11 + self.addLink( O14, O70, port1=102, port2=101, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 185, "durable": "true" }, cls=LINCLink ) # CLEVOH02 TOLDOH21 + self.addLink( O15, O48, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 312, "durable": "true" }, cls=LINCLink ) # CLMBOH11 PITBPADG + self.addLink( O18, O25, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 437, "durable": "true" }, cls=LINCLink ) # DLLSTXTL HSTNTX01 + self.addLink( O18, O32, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 563, "durable": "true" }, cls=LINCLink ) # DLLSTXTL LTRKARFR + self.addLink( O18, O42, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 365, "durable": "true" }, cls=LINCLink ) # DLLSTXTL OKCYOKCE + self.addLink( O19, O44, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 940, "durable": "true" }, cls=LINCLink ) # DNVRCOMA OMAHNENW + self.addLink( O19, O56, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 714, "durable": "true" }, cls=LINCLink ) # DNVRCOMA SLKCUTMA + self.addLink( O20, O70, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 103, "durable": "true" }, cls=LINCLink ) # DTRTMIBA TOLDOH21 + self.addLink( O21, O57, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 969, "durable": "true" }, cls=LINCLink ) # ELPSTXMA SNANTXCA + self.addLink( O21, O68, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 511, "durable": "true" }, cls=LINCLink ) # ELPSTXMA TCSNAZMA + self.addLink( O22, O31, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 505, "durable": "true" }, cls=LINCLink ) # FRSNCA01 LSVGNV02 + self.addLink( O22, O29, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 396, "durable": "true" }, cls=LINCLink ) # FRSNCA01 LSANCA03 + self.addLink( O22, O42, port1=103, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 298, "durable": "true" }, cls=LINCLink ) # FRSNCA01 OKLDCA03 + self.addLink( O23, O31, port1=101, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 697, "durable": "true" }, cls=LINCLink ) # GNBONCEU LSVLKYCS + self.addLink( O23, O52, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 130, "durable": "true" }, cls=LINCLink ) # GNBONCEU RLGHNCMO + self.addLink( O23, O51, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 319, "durable": "true" }, cls=LINCLink ) # GNBONCEU RCMDVAGR + self.addLink( O24, O28, port1=101, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 185, "durable": "true" }, cls=LINCLink ) # HRFRCT03 L_Island + self.addLink( O24, O49, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 125, "durable": "true" }, cls=LINCLink ) # HRFRCT03 PRVDRIGR + self.addLink( O26, O45, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 238, "durable": "true" }, cls=LINCLink ) # JCVLFLCL ORLDFLMA + self.addLink( O27, O44, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 320, "durable": "true" }, cls=LINCLink ) # KSCYMO09 OMAHNENW + self.addLink( O27, O64, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 457, "durable": "true" }, cls=LINCLink ) # KSCYMO09 STLSMO09 + self.addLink( O27, O71, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 420, "durable": "true" }, cls=LINCLink ) # KSCYMO09 TULSOKTB + self.addLink( O30, O47, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 494, "durable": "true" }, cls=LINCLink ) # LSVGNV02 PHNXAZMA + self.addLink( O30, O56, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 701, "durable": "true" }, cls=LINCLink ) # LSVGNV02 SLKCUTMA + self.addLink( O32, O35, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 249, "durable": "true" }, cls=LINCLink ) # LTRKARFR MMPHTNMA + self.addLink( O28, O41, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 40, "durable": "true" }, cls=LINCLink ) # L_Island NYCMNY54 + self.addLink( O29, O59, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 212, "durable": "true" }, cls=LINCLink ) # LSANCA03 SNDGCA02 + self.addLink( O29, O58, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 167, "durable": "true" }, cls=LINCLink ) # LSANCA03 SNBBCA01 + self.addLink( O31, O38, port1=104, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 298, "durable": "true" }, cls=LINCLink ) # LSVLKYCS NSVLTNMT + self.addLink( O31, O64, port1=102, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 468, "durable": "true" }, cls=LINCLink ) # LSVLKYCS STLSMO09 + self.addLink( O35, O38, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 380, "durable": "true" }, cls=LINCLink ) # MMPHTNMA NSVLTNMT + self.addLink( O33, O67, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 407, "durable": "true" }, cls=LINCLink ) # MIAMFLAC TAMQFLFN + self.addLink( O33, O74, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 125, "durable": "true" }, cls=LINCLink ) # MIAMFLAC WPBHFLAN + self.addLink( O34, O36, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 574, "durable": "true" }, cls=LINCLink ) # MILWWIHE MPLSMNDT + self.addLink( O36, O44, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 560, "durable": "true" }, cls=LINCLink ) # MPLSMNDT OMAHNENW + self.addLink( O39, O69, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 670, "durable": "true" }, cls=LINCLink ) # NWORLAMA TLHSFLAT + self.addLink( O41, O40, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 19, "durable": "true" }, cls=LINCLink ) # NYCMNY54 NWRKNJ02 + self.addLink( O41, O55, port1=102, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 187, "durable": "true" }, cls=LINCLink ) # NYCMNY54 SCTNPA01 + self.addLink( O41, O73, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 210, "durable": "true" }, cls=LINCLink ) # NYCMNY54 WLMGDE01 + self.addLink( O40, O46, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 146, "durable": "true" }, cls=LINCLink ) # NWRKNJ02 PHLAPASL + self.addLink( O37, O52, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 290, "durable": "true" }, cls=LINCLink ) # NRFLVABS RLGHNCMO + self.addLink( O37, O73, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 392, "durable": "true" }, cls=LINCLink ) # NRFLVABS WLMGDE01 + self.addLink( O43, O54, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 131, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SCRMCA01 + self.addLink( O43, O56, port1=102, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1142, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SLKCUTMA + self.addLink( O43, O60, port1=103, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 13, "durable": "true" }, cls=LINCLink ) # OKLDCA03 SNFCCA21 + self.addLink( O42, O71, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 188, "durable": "true" }, cls=LINCLink ) # OKCYOKCE TULSOKTB + self.addLink( O45, O74, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 290, "durable": "true" }, cls=LINCLink ) # ORLDFLMA WPBHFLAN + self.addLink( O46, O55, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 201, "durable": "true" }, cls=LINCLink ) # PHLAPASL SCTNPA01 + self.addLink( O47, O59, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 575, "durable": "true" }, cls=LINCLink ) # PHNXAZMA SNDGCA02 + self.addLink( O47, O68, port1=102, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 205, "durable": "true" }, cls=LINCLink ) # PHNXAZMA TCSNAZMA + self.addLink( O48, O55, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 457, "durable": "true" }, cls=LINCLink ) # PITBPADG SCTNPA01 + self.addLink( O50, O54, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 934, "durable": "true" }, cls=LINCLink ) # PTLDOR62 SCRMCA01 + self.addLink( O50, O56, port1=102, port2=108, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1225, "durable": "true" }, cls=LINCLink ) # PTLDOR62 SLKCUTMA + self.addLink( O50, O65, port1=103, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 280, "durable": "true" }, cls=LINCLink ) # PTLDOR62 STTLWA06 + self.addLink( O51, O72, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 184, "durable": "true" }, cls=LINCLink ) # RCMDVAGR WASHDCSW + self.addLink( O53, O66, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 143, "durable": "true" }, cls=LINCLink ) # ROCHNYXA SYRCNYSU + self.addLink( O60, O61, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 80., "durable": "true" }, cls=LINCLink ) # SNFCCA21 SNJSCA02 + self.addLink( O61, O58, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 455, "durable": "true" }, cls=LINCLink ) # SNJSCA02 SNBBCA01 + self.addLink( O55, O66, port1=101, port2=105, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 223, "durable": "true" }, cls=LINCLink ) # SCTNPA01 SYRCNYSU + self.addLink( O65, O63, port1=101, port2=107, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 442, "durable": "true" }, cls=LINCLink ) # STTLWA06 SPKNWA01 + self.addLink( O62, O64, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 165, "durable": "true" }, cls=LINCLink ) # SPFDILSD STLSMO09 + self.addLink( O69, O67, port1=101, port2=106, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 384, "durable": "true" }, cls=LINCLink ) # TLHSFLAT TAMQFLFN + + # Packet/Optical cross connect links (this will be the tap interfaces) + self.addLink( WASHDCSWR, O72, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( WASHDCSWR, O72, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNJSCA02R, O61, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( SNANTXCAR, O57, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ROCHNYXAR, O53, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( PHNXAZMAR, O47, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ORLDFLMAR, O45, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( NWRKNJ02R, O40, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( MPLSMNDTR, O36, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( LSANCA03R, O29, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( DLLSTXTLR, O18, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=4, port2=12, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=5, port2=13, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + self.addLink( ATLNGATLR, O4, port1=6, port2=14, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) + + + # Attach hosts to the packet layer switches + for i in range( 1, 4 ): #don't make this more than 4!!!!! + # Create Hosts 1..11 + h1 = self.addHost( 'h1d%d' % i, ip='10.0.1.%d/16' % i ) + h2 = self.addHost( 'h2d%d' % i, ip='10.0.2.%d/16' % i ) + h3 = self.addHost( 'h3d%d' % i, ip='10.0.3.%d/16' % i ) + h4 = self.addHost( 'h4d%d' % i, ip='10.0.4.%d/16' % i ) + h5 = self.addHost( 'h5d%d' % i, ip='10.0.5.%d/16' % i ) + h6 = self.addHost( 'h6d%d' % i, ip='10.0.6.%d/16' % i ) + h7 = self.addHost( 'h7d%d' % i, ip='10.0.7.%d/16' % i ) + h8 = self.addHost( 'h8d%d' % i, ip='10.0.8.%d/16' % i ) + h9 = self.addHost( 'h9d%d' % i, ip='10.0.9.%d/16' % i ) + h10 = self.addHost( 'h10d%d' % i, ip='10.0.10.%d/16' % i ) + h11 = self.addHost( 'h11d%d' % i, ip='10.0.11.%d/16' % i ) + + port = i + 6 + self.addLink( SNJSCA02R, h1, port1=port ) + self.addLink( SNANTXCAR, h2, port1=port ) + self.addLink( ROCHNYXAR, h3, port1=port ) + self.addLink( PHNXAZMAR, h4, port1=port ) + self.addLink( ORLDFLMAR, h5, port1=port ) + self.addLink( NWRKNJ02R, h6, port1=port ) + self.addLink( MPLSMNDTR, h7, port1=port ) + self.addLink( LSANCA03R, h8, port1=port ) + self.addLink( DLLSTXTLR, h9, port1=port ) + self.addLink( ATLNGATLR, h10, port1=port ) + self.addLink( WASHDCSWR, h11, port1=port ) + +if __name__ == '__main__': + import sys + if len( sys.argv ) >= 2: + controllers = sys.argv[1:] + else: + print 'Usage: sudo -E python opticalTestBig.py (<Controller IP>)+' + print 'Using localhost...\n' + controllers = [ '127.0.0.1' ] + + setLogLevel( 'info' ) + net = MininetOE( topo=BigOpticalTopo(), controller=None, autoSetMacs=True ) + net.addControllers( controllers ) + net.start() + CLI( net ) + net.stop() diff --git a/framework/src/onos/tools/test/topos/opticalUtils.py b/framework/src/onos/tools/test/topos/opticalUtils.py new file mode 100644 index 00000000..bef9deca --- /dev/null +++ b/framework/src/onos/tools/test/topos/opticalUtils.py @@ -0,0 +1,771 @@ +#!/usr/bin/python + +''' +Notes: + +This file contains classes and methods useful for integrating LincOE with Mininet, +such as startOE, stopOE, LINCLink, and OpticalSwitch + +- $ONOS_ROOT ust be set +- Need to run with sudo -E to preserve ONOS_ROOT env var +- We assume LINC-Config-Generator is named LINC-Config-Generator +- We also assume linc-oe is named linc-oe +- LINC-config-generator and linc-oe must be subdirectories of the user's + home directory + + TODO + ----------- + - clean up files after runtime + - maybe save the old files in a separate directory? + - modify script to allow startOE to run before net.start() + - add ONOS as a controller in script + + Usage: + ------------ + - import LINCLink and OpticalSwitch from this module + - import startOE and stopOE from this module + - create topology as you would a normal topology. when + to an optical switch with topo.addLink, always specify cls=LINCLink + - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch + - for annotations on links and switches, a dictionary must be passed in as + the annotations argument + - startOE must be run AFTER net.start() with net as an argument. + - stopOE can be run at any time + +I created a separate function to start lincOE to avoid subclassing Mininet. +In case anyone wants to write something that DOES subclass Mininet, I +thought I would outline how: + +If we want an object that starts lincOE within the mininet class itself, +we need to add another object to Mininet that contains all of the json object +information for each switch. We would still subclass switch and link, but these +classes would basically be dummy classes that store their own json information +in the Mininet class object. We may also change the default switch class to add +it's tap interfaces from lincOE during startup. The start() method for mininet would +grab all of the information from these switches and links, write configuration files +for lincOE using the json module, start lincOE, then run the start methodfor each +switch. The new start() method for each switch would parse through the sys.config +file that was created and find the tap interface it needs to connect to, similar +to the findTap function that I currently use. After all of the controllers and +switches have been started, the new Mininet start() method should also push the +Topology configuration file to ONOS. + +''' +import sys +import re +import json +import os +from time import sleep +import urllib2 + +from mininet.node import Switch, RemoteController +from mininet.topo import Topo +from mininet.util import quietRun +from mininet.net import Mininet +from mininet.log import setLogLevel, info, error, warn +from mininet.link import Link, Intf +from mininet.cli import CLI + +# Sleep time and timeout values in seconds +SLEEP_TIME = 2 +TIMEOUT = 60 + +REST_USER = 'onos' +REST_PW = 'rocks' + +class OpticalSwitch(Switch): + """ + For now, same as Switch class. + """ + pass + +class OpticalIntf(Intf): + """ + For now,same as Intf class. + """ + pass + +class OpticalLink(Link): + """ + For now, same as Link. + """ + pass + +class LINCSwitch(OpticalSwitch): + """ + LINCSwitch class + """ + # FIXME:Sometimes LINC doesn't remove pipes and on restart increase the pipe + # number from erlang.pipe.1.* to erlang.pipe.2.*, so should read and write + # from latest pipe files. For now we are removing all the pipes before + # starting LINC. + ### User Name ### + user = os.getlogin() + ### pipes ### + readPipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.r".format(user) + writePipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.w".format(user) + ### sys.config path ### + sysConfig = "/home/{}/linc-oe/rel/linc/releases/1.0/sys.config".format(user) + ### method, mapping dpid to LINC switchId ### + @staticmethod + def dpids_to_ids(sysConfig): + ''' + return the dict containing switch dpids as key and LINC switch id as values + ''' + dpids_to_ids = {} + fd = None + try: + with open(sysConfig, 'r', 0) as fd: + switch_id = 1 + for line in fd: + dpid = re.search(r'([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})+', line, re.I) + if dpid: + dpids_to_ids[dpid.group().replace(':', '')] = switch_id + switch_id += 1 + return dpids_to_ids + except: + print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info()) + fd.close() + return None + ### dict of containing dpids as key and corresponding LINC switchId as values ### + dpidsToLINCSwitchId = dpids_to_ids.__func__(sysConfig) + @staticmethod + def findDir(directory, userName): + "finds and returns the path of any directory in the user's home directory" + homeDir = '/home/' + userName + Dir = quietRun('find %s -maxdepth 1 -name %s -type d' % (homeDir, directory)).strip('\n') + DirList = Dir.split('\n') + if not Dir: + return None + elif len(DirList) > 1 : + warn('***WARNING: Found multiple instances of %s; using %s\n' + % (directory, DirList[ 0 ])) + return DirList[ 0 ] + else: + return Dir + ### ONOS Directory ### + try: + onosDir = os.environ[ 'ONOS_ROOT' ] + except: + onosDir = findDir('onos', user) + if not onosDir: + error('Please set ONOS_ROOT environment variable!\n') + else: + os.environ[ 'ONOS_ROOT' ] = onosDir + ### LINC-directory + lincDir = findDir.__func__('linc-oe', user) + if not lincDir: + error("***ERROR: Could not find linc-oe in user's home directory\n") + ### LINC config generator directory### + configGen = findDir.__func__('LINC-config-generator', user) + if not configGen: + error("***ERROR: Could not find LINC-config-generator in user's home directory\n") + # list of all the controllers + controllers = None + def __init__(self, name, dpid=None, allowed=True, + switchType='ROADM', topo=None, annotations={}, controller=None, **params): + params[ 'inNamespace' ] = False + Switch.__init__(self, name, dpid=dpid, **params) + self.name = name + self.annotations = annotations + self.allowed = allowed + self.switchType = switchType + self.configDict = {} # dictionary that holds all of the JSON configuration data + self.crossConnects = [] + self.deletedCrossConnects = [] + self.controller = controller + self.lincId = self._get_linc_id() # use to communicate with LINC + self.lincStarted = False + + def start(self, *opts, **params): + '''Instead of starting a virtual switch, we build the JSON + dictionary for the emulated optical switch''' + # TODO:Once LINC has the ability to spawn network element dynamically + # we need to use this method to spawn new logical LINC switch rather then + # bulding JSON. + # if LINC is started then we can start and stop logical switches else create JSON + if self.lincStarted: + return self.start_oe() + self.configDict[ 'uri' ] = 'of:' + self.dpid + self.configDict[ 'annotations' ] = self.annotations + self.configDict[ 'annotations' ].setdefault('name', self.name) + self.configDict[ 'hw' ] = 'LINC-OE' + self.configDict[ 'mfr' ] = 'Linc' + self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1] + self.configDict[ 'type' ] = self.switchType + self.configDict[ 'ports' ] = [] + for port, intf in self.intfs.items(): + if intf.name == 'lo': + continue + else: + self.configDict[ 'ports' ].append(intf.json()) + self.lincStarted = True + + def stop(self, deleteIntfs=False): + ''' + stop the existing switch + ''' + # TODO:Add support for deleteIntf + self.stop_oe() + + def dpctl( self, *args ): + "Run dpctl command: ignore for now" + pass + + def write_to_cli(self, command): + ''' + send command to LINC + ''' + fd = None + try: + fd = open(self.writePipe, 'w', 0) + fd.write(command) + fd.close() + except: + print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info()) + if fd: + fd.close() + + def read_from_cli(self): + ''' + read the output from the LINC CLI + ''' + response = None + fd = None + try: + fd = open(self.readPipe, 'r', 0) + fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) # for non-blocking read + # FIXME:Due to non-blocking read most for the time we read nothing + response = fd.read() + fd.close() + except : + # print "Error working with {}\nError: {}\n".format(self.readPipe, sys.exc_info()) + if fd: + fd.close() + return response + + def _get_linc_id(self): + ''' + return the corresponding LINC switchId. + ''' + return LINCSwitch.dpidsToLINCSwitchId.get(self.dpid) + #-------------------------------------------------------------------------- + # LINC CLI commands + #-------------------------------------------------------------------------- + def start_oe(self): + ''' + existing LINC switch + ''' + #starting Switch + cmd = "linc:start_switch({}).\r\n".format(self.lincId) + self.write_to_cli(cmd) + #hanlding taps interfaces related to the switch + crossConnectJSON = {} + linkConfig = [] + for i in range(0,len(self.deletedCrossConnects)): + crossConnect = self.deletedCrossConnects.pop() + tap = None + if isinstance(crossConnect.intf1.node, LINCSwitch): + intf = crossConnect.intf2 + tapPort = crossConnect.intf1.port + else: + intf = crossConnect.intf1 + tapPort = crossConnect.intf2.port + tap = LINCSwitch.findTap(self, tapPort) + if tap: + LINCSwitch.setupInts([tap]) + intf.node.attach(tap) + self.crossConnects.append(crossConnect) + linkConfig.append(crossConnect.json()) + #Sending crossConnect info to the ONOS. + crossConnectJSON['links'] = linkConfig + with open("crossConnect.json", 'w') as fd: + json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': ')) + info('*** Pushing crossConnect.json to ONOS\n') + output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\ + Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True) + + def stop_oe(self): + ''' + stop the existing LINC switch + ''' + cmd = "linc:stop_switch({}).\r\n".format(self.lincId) + self.write_to_cli(cmd) + #handling taps if any + for i in range(0, len(self.crossConnects)): + crossConnect = self.crossConnects.pop() + if isinstance(crossConnect.intf1.node, LINCSwitch): + intf = crossConnect.intf2 + tapPort = crossConnect.intf1.port + else: + intf = crossConnect.intf1 + tapPort = crossConnect.intf2.port + intf.node.detach(LINCSwitch.findTap(self, tapPort)) + self.deletedCrossConnects.append(crossConnect) + + def w_port_up(self, port): + ''' + port_up + ''' + cmd = "linc:port_up({},{}).\r\n".format(self.lincId, port) + self.write_to_cli(cmd) + + def w_port_down(self, port): + ''' + port_down + ''' + cmd = "linc:port_down({},{}).\r\n".format(self.lincId, port) + self.write_to_cli(cmd) + + # helper functions + @staticmethod + def switchJSON(switch): + "Returns the json configuration for a packet switch" + configDict = {} + configDict[ 'uri' ] = 'of:' + switch.dpid + configDict[ 'mac' ] = quietRun('cat /sys/class/net/%s/address' % switch.name).strip('\n').translate(None, ':') + configDict[ 'hw' ] = 'PK' # FIXME what about OVS? + configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS? + configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS? + annotations = switch.params.get('annotations', {}) + annotations.setdefault('name', switch.name) + configDict[ 'annotations' ] = annotations + ports = [] + for port, intf in switch.intfs.items(): + if intf.name == 'lo': + continue + portDict = {} + portDict[ 'port' ] = port + portDict[ 'type' ] = 'FIBER' if isinstance(intf.link, LINCLink) else 'COPPER' + intfList = [ intf.link.intf1, intf.link.intf2 ] + intfList.remove(intf) + portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0 + ports.append(portDict) + configDict[ 'ports' ] = ports + return configDict + + @staticmethod + def bootOE(net): + "Start the LINC optical emulator within a mininet instance" + LINCSwitch.opticalJSON = {} + linkConfig = [] + devices = [] + #setting up the controllers for LINCSwitch class + LINCSwitch.controllers = net.controllers + + for switch in net.switches: + if isinstance(switch, OpticalSwitch): + devices.append(switch.json()) + else: + devices.append(LINCSwitch.switchJSON(switch)) + LINCSwitch.opticalJSON[ 'devices' ] = devices + + for link in net.links: + if isinstance(link, LINCLink) : + linkConfig.append(link.json()) + LINCSwitch.opticalJSON[ 'links' ] = linkConfig + + info('*** Writing Topology.json file\n') + with open('Topology.json', 'w') as outfile: + json.dump(LINCSwitch.opticalJSON, outfile, indent=4, separators=(',', ': ')) + + info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file (no oecfg) \n') + + topoConfigJson = {}; + dpIdToName = {}; + + topoConfigJson["switchConfig"] = LINCSwitch.getSwitchConfig(dpIdToName); + topoConfigJson["linkConfig"] = LINCSwitch.getLinkConfig(dpIdToName); + + #Writing to TopoConfig.json + with open( 'TopoConfig.json', 'w' ) as outfile: + json.dump( topoConfigJson, outfile, indent=4, separators=(',', ': ') ) + + info('*** Creating sys.config...\n') + output = quietRun('%s/config_generator TopoConfig.json %s/sys.config.template %s %s' + % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[ 0 ].ip, LINCSwitch.controllers[ 0 ].port), shell=True) + if output: + error('***ERROR: Error creating sys.config file: %s\n' % output) + return False + + info ('*** Setting multiple controllers in sys.config...\n') + searchStr = '\[{"Switch.*$' + ctrlStr = '' + for index in range(len(LINCSwitch.controllers)): + ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port) + replaceStr = '[%s]},' % ctrlStr[:-1] # Cut off last comma + sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr) + output = quietRun(sedCmd, shell=True) + + info('*** Copying sys.config to linc-oe directory: ', output + '\n') + output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n') + info(output + '\n') + + info('*** Adding taps and bringing them up...\n') + LINCSwitch.setupInts(LINCSwitch.getTaps()) + + info('*** removing pipes if any \n') + quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True) + + info('*** Starting linc OE...\n') + output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True) + if output: + error('***ERROR: LINC-OE: %s' % output + '\n') + quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) + return False + + info('*** Waiting for linc-oe to start...\n') + LINCSwitch.waitStarted(net) + + info('*** Adding cross-connect (tap) interfaces to packet switches...\n') + for link in net.links: + if isinstance(link, LINCLink): + if link.annotations[ 'optical.type' ] == 'cross-connect': + for intf in [ link.intf1, link.intf2 ]: + if not isinstance(intf, LINCIntf): + intfList = [ intf.link.intf1, intf.link.intf2 ] + intfList.remove(intf) + intf2 = intfList[ 0 ] + intf.node.attach(LINCSwitch.findTap(intf2.node, intf2.node.ports[ intf2 ])) + + info('*** Waiting for all devices to be available in ONOS...\n') + url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip + time = 0 + # Set up password authentication + pw_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() + pw_mgr.add_password(None, url, REST_USER, REST_PW) + handler = urllib2.HTTPBasicAuthHandler(pw_mgr) + opener = urllib2.build_opener(handler) + opener.open(url) + urllib2.install_opener(opener) + while True: + response = json.load(urllib2.urlopen(url)) + devs = response.get('devices') + + # Wait for all devices to be registered + if (len(devices) != len(devs)): + continue + + # Wait for all devices to available + available = True + for d in devs: + available &= d['available'] + if available: + break + + if (time >= TIMEOUT): + error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT) + break + + time += SLEEP_TIME + sleep(SLEEP_TIME) + + info('*** Pushing Topology.json to ONOS\n') + for index in range(len(LINCSwitch.controllers)): + output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json &' % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True) + # successful output contains the two characters '{}' + # if there is more output than this, there is an issue + if output.strip('{}'): + warn('***WARNING: Could not push topology file to ONOS: %s\n' % output) + + #converts node ids to linc-oe format, with colons every two chars + @staticmethod + def dpId(id): + nodeDpid = "" + id = id.split("/", 1)[0] + for i in range(3, len(id) - 1, 2): + nodeDpid += (id[i:(i + 2):]) + ":" + return nodeDpid[0:-1]; + + @staticmethod + def getSwitchConfig (dpIdToName): + switchConfig = []; + #Iterate through all switches and convert the ROADM switches to linc-oe format + for switch in LINCSwitch.opticalJSON["devices"]: + if switch.get("type", "none") == "ROADM": + builtSwitch = {} + + #set basic switch params based on annotations + builtSwitch["allowed"] = True; + builtSwitch["latitude"] = switch["annotations"].get("latitude", 0.0); + builtSwitch["longitude"] = switch["annotations"].get("longitude", 0.0); + + #assumed that all switches have this entry + nodeId = switch["uri"] + + #convert the nodeId to linc-oe format + nodeDpid = LINCSwitch.dpId(nodeId); + + builtSwitch["name"] = switch.get("name", "none"); + + #keep track of the name corresponding to each switch dpid + dpIdToName[nodeDpid] = builtSwitch["name"]; + + builtSwitch["nodeDpid"] = nodeDpid + + #set switch params and type + builtSwitch["params"] = {}; + builtSwitch["params"]["numregens"] = switch["annotations"].get("optical.regens", 0); + builtSwitch["type"] = "Roadm" + + #append to list of switches + switchConfig.append(builtSwitch); + return switchConfig + + @staticmethod + def getLinkConfig (dpIdToName): + newLinkConfig = []; + #Iterate through all optical links and convert them to linc-oe format + for link in LINCSwitch.opticalJSON["links"]: + if link.get("type", "none") == "OPTICAL": + builtLink = {} + + #set basic link params for src and dst + builtLink["allowed"] = True; + builtLink["nodeDpid1"] = LINCSwitch.dpId(link["src"]) + builtLink["nodeDpid2"] = LINCSwitch.dpId(link["dst"]) + + #set more params such as name/bandwidth/port/waves if they exist + params = {} + params["nodeName1"] = dpIdToName.get(builtLink["nodeDpid1"], "none") + params["nodeName2"] = dpIdToName.get(builtLink["nodeDpid2"], "none") + + params["port1"] = int(link["src"].split("/")[1]) + params["port2"] = int(link["dst"].split("/")[1]) + + if "bandwidth" in link["annotations"]: + params["bandwidth"] = link["annotations"]["bandwidth"] + + if "optical.waves" in link["annotations"]: + params["numWaves"] = link["annotations"]["optical.waves"] + + builtLink["params"] = params + + #set type of link (WDM or pktOpt) + if link["annotations"].get("optical.type", "cross-connect") == "WDM": + builtLink["type"] = "wdmLink" + else: + builtLink["type"] = "pktOptLink" + + newLinkConfig.append(builtLink); + return newLinkConfig + + + @staticmethod + def waitStarted(net, timeout=TIMEOUT): + "wait until all tap interfaces are available" + tapCount = 0 + time = 0 + for link in net.links: + if isinstance(link, LINCLink): + if link.annotations[ 'optical.type' ] == 'cross-connect': + tapCount += 1 + + while True: + if str(tapCount) == quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'): + return True + if timeout: + if time >= TIMEOUT: + error('***ERROR: LINC OE did not start within %s seconds\n' % TIMEOUT) + return False + time += SLEEP_TIME + sleep(SLEEP_TIME) + + @staticmethod + def shutdownOE(): + "stop the optical emulator" + info('*** Stopping linc OE...\n') + quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) + + @staticmethod + def setupInts(intfs): + ''' + add taps and bring them up. + ''' + for i in intfs: + quietRun('ip tuntap add dev %s mode tap' % i) + quietRun('ip link set dev %s up' % i) + info('*** Intf %s set\n' % i) + + @staticmethod + def getTaps(path=None): + ''' + return list of all the tops in sys.config + ''' + if path is None: + path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir + fd = open(path, 'r', 0) + sys_data = fd.read() + taps = re.findall('tap\d+', sys_data) + fd.close() + return taps + + @staticmethod + def findUser(): + "Try to return logged-in (usually non-root) user" + try: + # If we're running sudo + return os.environ[ 'SUDO_USER' ] + except: + try: + # Logged-in user (if we have a tty) + return quietRun('who am i').split()[ 0 ] + except: + # Give up and return effective user + return quietRun('whoami') + + + @staticmethod + def findTap(node, port, path=None): + '''utility function to parse through a sys.config + file to find tap interfaces for a switch''' + switch = False + portLine = '' + intfLines = [] + + if path is None: + path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir + + with open(path) as f: + for line in f: + if 'tap' in line: + intfLines.append(line) + if node.dpid in line.translate(None, ':'): + switch = True + continue + if switch: + if 'switch' in line: + switch = False + if 'port_no,%s}' % port in line: + portLine = line + break + + if portLine: + m = re.search('port,\d+', portLine) + port = m.group(0).split(',')[ 1 ] + else: + error('***ERROR: Could not find any ports in sys.config\n') + return + + for intfLine in intfLines: + if 'port,%s' % port in intfLine: + return re.findall('tap\d+', intfLine)[ 0 ] + + def json(self): + "return json configuration dictionary for switch" + return self.configDict + + def terminate(self): + pass + + + +class LINCLink(Link): + """ + LINC link class + """ + def __init__(self, node1, node2, port1=None, port2=None, allowed=True, + intfName1=None, intfName2=None, linkType='OPTICAL', + annotations={}, speed1=0, speed2=0, **params): + "Creates a dummy link without a virtual ethernet pair." + self.allowed = allowed + self.annotations = annotations + self.linkType = linkType + self.port1 = port1 + self.port2 = port2 + params1 = { 'speed': speed1 } + params2 = { 'speed': speed2 } + # self.isCrossConnect = True if self.annotations.get('optical.type') == 'cross-connect' else False + if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch): + self.isCrossConnect = False + else: + self.isCrossConnect = True + if isinstance(node1, LINCSwitch): + cls1 = LINCIntf + if self.isCrossConnect: + node1.crossConnects.append(self) + else: + cls1 = Intf + # bad hack to stop error message from appearing when we try to set up intf in a packet switch, + # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up + intfName1 = 'lo' + if isinstance(node2, LINCSwitch): + cls2 = LINCIntf + if self.isCrossConnect: + node2.crossConnects.append(self) + else: + cls2 = Intf + intfName2 = 'lo' + Link.__init__(self, node1, node2, port1=port1, port2=port2, + intfName1=intfName1, intfName2=intfName2, cls1=cls1, + cls2=cls2, params1=params1, params2=params2) + + @classmethod + def makeIntfPair(_cls, intfName1, intfName2, *args, **kwargs): + pass + + def json(self): + "build and return the json configuration dictionary for this link" + configData = {} + configData[ 'src' ] = ('of:' + self.intf1.node.dpid + + '/%s' % self.intf1.node.ports[ self.intf1 ]) + configData[ 'dst' ] = ('of:' + self.intf2.node.dpid + + '/%s' % self.intf2.node.ports[ self.intf2 ]) + configData[ 'type' ] = self.linkType + configData[ 'annotations' ] = self.annotations + return configData + +class LINCIntf(OpticalIntf): + """ + LINC interface class + """ + def __init__(self, name=None, node=None, speed=0, + port=None, link=None, **params): + self.node = node + self.speed = speed + self.port = port + self.link = link + self.name = name + node.addIntf(self, port=port) + self.params = params + self.ip = None + + def json(self): + "build and return the JSON information for this interface( not used right now )" + configDict = {} + configDict[ 'port' ] = self.port + configDict[ 'speed' ] = self.speed + configDict[ 'type' ] = 'FIBER' + return configDict + + def config(self, *args, **kwargs): + "dont configure a dummy interface" + pass + + def ifconfig(self, status): + "configure the status" + if status == "up": + return self.node.w_port_up(self.port) + elif status == "down": + return self.node.w_port_down(self.port) + + +class MininetOE(Mininet): + "Mininet with Linc-OE support (starts and stops linc-oe)" + + def start(self): + Mininet.start(self) + LINCSwitch.bootOE(self) + + def stop(self): + Mininet.stop(self) + LINCSwitch.shutdownOE() + + def addControllers(self, controllers): + i = 0 + for ctrl in controllers: + self.addController(RemoteController('c%d' % i, ip=ctrl)) + i += 1 + +if __name__ == '__main__': + pass diff --git a/framework/src/onos/tools/test/topos/rftest.py b/framework/src/onos/tools/test/topos/rftest.py new file mode 100644 index 00000000..7aba54f9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/rftest.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +import sys + +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.node import RemoteController + +from rftesttopo import ReactiveForwardingTestTopo + +setLogLevel( 'info' ) + +def pingloop( net ): + setLogLevel( 'error' ) + try: + while True: + net.ping() + finally: + setLogLevel( 'info' ) + +def run(controllers=[ '127.0.0.1' ]): + Mininet.pingloop = pingloop + net = Mininet( topo=ReactiveForwardingTestTopo(), build=False, autoSetMacs=True ) + ctrl_count = 0 + for controllerIP in controllers: + net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + ctrl_count = ctrl_count + 1 + net.build() + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + if len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Usage: rf-test.py <c0 IP> <c1 IP> ...' + exit( 1 ) + run( controllers ) diff --git a/framework/src/onos/tools/test/topos/rftesttopo.py b/framework/src/onos/tools/test/topos/rftesttopo.py new file mode 100644 index 00000000..9b975785 --- /dev/null +++ b/framework/src/onos/tools/test/topos/rftesttopo.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +""" +""" +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.node import RemoteController +from mininet.node import Node +from mininet.node import CPULimitedHost +from mininet.link import TCLink +from mininet.cli import CLI +from mininet.log import setLogLevel +from mininet.util import dumpNodeConnections + +class ReactiveForwardingTestTopo( Topo ): + "Internet Topology Zoo Specimen." + + def __init__( self ): + "Create a topology." + + # Initialize Topology + Topo.__init__( self ) + + # add nodes, switches first... + s1 = self.addSwitch( 's1' ) + s2 = self.addSwitch( 's2' ) + s3 = self.addSwitch( 's3' ) + s4 = self.addSwitch( 's4' ) + s5 = self.addSwitch( 's5' ) + s6 = self.addSwitch( 's6' ) + s7 = self.addSwitch( 's7' ) + s8 = self.addSwitch( 's8' ) + s9 = self.addSwitch( 's9' ) + + # ... and now hosts + h1 = self.addHost( 'h1' ) + h2 = self.addHost( 'h2' ) + h3 = self.addHost( 'h3' ) + h4 = self.addHost( 'h4' ) + + # add edges between switch and corresponding host + self.addLink( s1 , h1 ) + self.addLink( s2 , h2 ) + self.addLink( s3 , h3 ) + self.addLink( s4 , h4 ) + + # add edges between switches + self.addLink( s1 , s5 ) + self.addLink( s2 , s5 ) + self.addLink( s2 , s8 ) + self.addLink( s3 , s4 ) + self.addLink( s3 , s7 ) + self.addLink( s4 , s5 ) + self.addLink( s6 , s8 ) + self.addLink( s6 , s7 ) + self.addLink( s5 , s9 ) + self.addLink( s6 , s9 ) + +topos = { 'att': ( lambda: ReactiveForwardingTestTopo() ) } diff --git a/framework/src/onos/tools/test/topos/sdn-ip.json b/framework/src/onos/tools/test/topos/sdn-ip.json new file mode 100644 index 00000000..153d9959 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sdn-ip.json @@ -0,0 +1,26 @@ +{ + "devices": [ + { "alias": "s1", "uri": "of:0000000000000001", "mac": "000000000001", "annotations": { "name": "DEN", "latitude": 39.739317, "longitude": -104.983791 }, "type": "SWITCH" }, + { "alias": "s2", "uri": "of:0000000000000002", "mac": "000000000002", "annotations": { "name": "IND", "latitude": 39.769089, "longitude": -86.158039 }, "type": "SWITCH" }, + { "alias": "s3", "uri": "of:0000000000000003", "mac": "000000000003", "annotations": { "name": "ABQ", "latitude": 35.116541, "longitude": -106.604146 }, "type": "SWITCH" }, + { "alias": "s4", "uri": "of:0000000000000004", "mac": "000000000004", "annotations": { "name": "DFW", "latitude": 32.779501, "longitude": -96.801104 }, "type": "SWITCH" }, + { "alias": "s5", "uri": "of:0000000000000005", "mac": "000000000005", "annotations": { "name": "PDX", "latitude": 45.522585, "longitude": -122.677890 }, "type": "SWITCH" }, + { "alias": "s6", "uri": "of:0000000000000006", "mac": "000000000006", "annotations": { "name": "SFO", "latitude": 37.785286, "longitude": -122.406509 }, "type": "SWITCH" }, + { "alias": "s7", "uri": "of:0000000000000007", "mac": "000000000007", "annotations": { "name": "LAX", "latitude": 34.055604, "longitude": -118.248567 }, "type": "SWITCH" }, + { "alias": "s8", "uri": "of:0000000000000008", "mac": "000000000008", "annotations": { "name": "JFK", "latitude": 40.769487, "longitude": -73.972520 }, "type": "SWITCH" }, + { "alias": "s9", "uri": "of:0000000000000009", "mac": "000000000009", "annotations": { "name": "IAD", "latitude": 38.897676, "longitude": -77.036525 }, "type": "SWITCH" }, + { "alias": "s10", "uri": "of:0000000000000010", "mac": "000000000010", "annotations": { "name": "ATL", "latitude": 33.756298, "longitude": -84.388507 }, "type": "SWITCH" } + ], + + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:0000000000000001/10", "ip": "10.0.1.2, 10.0.2.2", "annotations": { "type": "bgpSpeaker", "latitude": 42.292306, "longitude": -104.084378 } }, + { "mac": "00:00:00:00:00:02", "vlan": -1, "location": "of:0000000000000002/10", "ip": "10.0.11.2, 10.0.22.2, 10.0.3.2, 10.0.4.2", "annotations": { "type": "bgpSpeaker", "latitude": 41.019068, "longitude": -91.079570 } }, + { "mac": "00:00:00:00:00:03", "vlan": -1, "location": "of:0000000000000003/10", "ip": "10.0.33.2, 10.0.44.2", "annotations": { "type": "bgpSpeaker", "latitude": 32.043892, "longitude": -105.644437 } }, + { "mac": "00:00:00:00:01:01", "vlan": -1, "location": "of:0000000000000005/10", "ip": "10.0.1.1", "annotations": { "type": "router", "latitude": 42.985256, "longitude": -127.074018 } }, + { "mac": "00:00:00:00:01:02", "vlan": -1, "location": "of:0000000000000006/10", "ip": "10.0.11.1", "annotations": { "type": "router", "latitude": 40.593824, "longitude": -127.074018 } }, + { "mac": "00:00:00:00:02:01", "vlan": -1, "location": "of:0000000000000007/10", "ip": "10.0.2.1, 10.0.22.1", "annotations": { "type": "router", "latitude": 31.277098, "longitude": -121.35488 } }, + { "mac": "00:00:00:00:03:01", "vlan": -1, "location": "of:0000000000000008/10", "ip": "10.0.3.1, 10.0.33.1", "annotations": { "type": "router", "latitude": 39.368502, "longitude": -69.976271 } }, + { "mac": "00:00:00:00:04:01", "vlan": -1, "location": "of:0000000000000009/10", "ip": "10.0.4.1", "annotations": { "type": "router", "latitude": 34.936264, "longitude": -75.526168 } }, + { "mac": "00:00:00:00:44:01", "vlan": -1, "location": "of:0000000000000010/10", "ip": "10.0.44.1", "annotations": { "type": "router", "latitude": 32.863420, "longitude": -77.505795 } } + ] +} diff --git a/framework/src/onos/tools/test/topos/sol.py b/framework/src/onos/tools/test/topos/sol.py new file mode 100755 index 00000000..68f2d406 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sol.py @@ -0,0 +1,4 @@ +#!/usr/bin/python +import sys, solar +topo = solar.Solar(cips=sys.argv[1:]) +topo.run() diff --git a/framework/src/onos/tools/test/topos/solar.py b/framework/src/onos/tools/test/topos/solar.py new file mode 100644 index 00000000..ea11b664 --- /dev/null +++ b/framework/src/onos/tools/test/topos/solar.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +from mininet.cli import CLI +from mininet.net import Mininet +from mininet.node import RemoteController, OVSKernelSwitch + +MAC = 12 +DPID = 16 + +class CustomCLI(CLI): + """Custom CLI to allow us to add our own commands.""" + + def __init__ (self, net): + """Init method for our custom CLI.""" + self.net = net + CLI.__init__(self, net) + +class Solar(object): + """ Create a tiered topology from semi-scratch in Mininet """ + + def __init__(self, cname='onos', cips=['192.168.56.1'], islands=3, edges=2, hosts=2): + """Create tower topology for mininet""" + + # We are creating the controller with local-loopback on purpose to avoid + # having the switches connect immediately. Instead, we'll set controller + # explicitly for each switch after configuring it as we want. + self.ctrls = [ RemoteController(cname, cip, 6633) for cip in cips ] + self.net = Mininet(controller=RemoteController, switch = OVSKernelSwitch, + build=False) + + self.cips = cips + self.spines = [] + self.leaves = [] + self.hosts = [] + for ctrl in self.ctrls: + self.net.addController(ctrl) + + # Create the two core switches and links between them + c1 = self.net.addSwitch('c1',dpid='1111000000000000') + c2 = self.net.addSwitch('c2',dpid='2222000000000000') + self.spines.append(c1) + self.spines.append(c2) + + self.net.addLink(c1, c2) + self.net.addLink(c2, c1) + + for i in range(1, islands + 1): + sc = self.createSpineClump(i, edges, hosts) + self.net.addLink(c1, sc[0]) + self.net.addLink(c2, sc[0]) + self.net.addLink(c1, sc[1]) + self.net.addLink(c2, sc[1]) + + def createSpineClump(self, island, edges, hosts): + """ Creates a clump of spine and edge switches with hosts""" + s1 = self.net.addSwitch('s%1d1' % island,dpid='00000%1d0100000000' % island) + s2 = self.net.addSwitch('s%1d2' % island,dpid='00000%1d0200000000' % island) + self.net.addLink(s1, s2) + self.net.addLink(s2, s1) + + for i in range(1, edges + 1): + es = self.createEdgeSwitch(island, i, hosts) + self.net.addLink(es, s1) + self.net.addLink(es, s2) + + self.spines.append(s1) + self.spines.append(s2) + + clump = [] + clump.append(s1) + clump.append(s2) + return clump + + def createEdgeSwitch(self, island, index, hosts): + """ Creates an edge switch in an island and ads hosts to it""" + sw = self.net.addSwitch('e%1d%1d' % (island, index),dpid='0000000%1d0000000%1d' % (island, index)) + self.leaves.append(sw) + + for j in range(1, hosts + 1): + host = self.net.addHost('h%d%d%d' % (island, index, j),ip='10.%d.%d.%d' % (island, index, j)) + self.net.addLink(host, sw) + self.hosts.append(host) + return sw + + def run(self): + """ Runs the created network topology and launches mininet cli""" + self.net.build() + self.net.start() + CustomCLI(self.net) + self.net.stop() + + def pingAll(self): + """ PingAll to create flows - for unit testing """ + self.net.pingAll() + + def stop(self): + "Stops the topology. You should call this after run_silent" + self.net.stop() diff --git a/framework/src/onos/tools/test/topos/sys-nonlinear-10.config b/framework/src/onos/tools/test/topos/sys-nonlinear-10.config new file mode 100644 index 00000000..2b999d39 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys-nonlinear-10.config @@ -0,0 +1,183 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"dummy"},{type,optical}]}, + {port,4,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,11,[{interface,"dummy"},{type,optical}]}, + {port,12,[{interface,"dummy"},{type,optical}]}, + {port,13,[{interface,"dummy"},{type,optical}]}, + {port,14,[{interface,"dummy"},{type,optical}]}, + {port,15,[{interface,"dummy"},{type,optical}]}, + {port,16,[{interface,"dummy"},{type,optical}]}, + {port,17,[{interface,"dummy"},{type,optical}]}, + {port,18,[{interface,"dummy"},{type,optical}]}, + {port,19,[{interface,"dummy"},{type,optical}]}, + {port,20,[{interface,"dummy"},{type,optical}]}, + {port,21,[{interface,"dummy"},{type,optical}]}, + {port,22,[{interface,"dummy"},{type,optical}]}, + {port,23,[{interface,"dummy"},{type,optical}]}, + {port,24,[{interface,"dummy"},{type,optical}]}, + {port,25,[{interface,"dummy"},{type,optical}]}, + {port,26,[{interface,"dummy"},{type,optical}]}, + {port,27,[{interface,"dummy"},{type,optical}]}, + {port,28,[{interface,"dummy"},{type,optical}]}, + {port,29,[{interface,"tap29"}]}, + {port,30,[{interface,"tap30"}]}, + {port,31,[{interface,"tap31"}]}, + {port,32,[{interface,"tap32"}]}, + {port,33,[{interface,"tap33"}]}, + {port,34,[{interface,"tap34"}]}]}, + {capable_switch_queues,[]}, + {optical_links, + [{{1,50},{2,30}}, + {{2,50},{3,30}}, + {{3,50},{4,50}}, + {{1,20},{5,50}}, + {{2,20},{5,20}}, + {{3,20},{6,50}}, + {{4,20},{6,20}}, + {{5,30},{6,40}}, + {{5,40},{7,50}}, + {{6,30},{8,50}}, + {{7,20},{8,30}}, + {{7,30},{9,50}}, + {{8,20},{10,50}}, + {{9,20},{10,20}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,50}]}, + {port,7,[{queues,[]},{port_no,20}]}, + {port,29,[{queues,[]},{port_no,10}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,30}]}, + {port,3,[{queues,[]},{port_no,50}]}, + {port,9,[{queues,[]},{port_no,20}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,4,[{queues,[]},{port_no,30}]}, + {port,5,[{queues,[]},{port_no,50}]}, + {port,11,[{queues,[]},{port_no,20}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,6,[{queues,[]},{port_no,50}]}, + {port,13,[{queues,[]},{port_no,20}]}, + {port,30,[{queues,[]},{port_no,10}]}]}]}, + {switch,5, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:05"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,8,[{queues,[]},{port_no,50}]}, + {port,10,[{queues,[]},{port_no,20}]}, + {port,15,[{queues,[]},{port_no,30}]}, + {port,17,[{queues,[]},{port_no,40}]}]}]}, + {switch,7, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:07"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,18,[{queues,[]},{port_no,50}]}, + {port,21,[{queues,[]},{port_no,20}]}, + {port,23,[{queues,[]},{port_no,30}]}, + {port,32,[{queues,[]},{port_no,10}]}]}]}, + {switch,8, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:08"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,20,[{queues,[]},{port_no,50}]}, + {port,22,[{queues,[]},{port_no,30}]}, + {port,25,[{queues,[]},{port_no,20}]}]}]}, + {switch,9, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:09"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,24,[{queues,[]},{port_no,50}]}, + {port,27,[{queues,[]},{port_no,20}]}, + {port,33,[{queues,[]},{port_no,10}]}]}]}, + {switch,10, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:0A"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,26,[{queues,[]},{port_no,50}]}, + {port,28,[{queues,[]},{port_no,20}]}, + {port,34,[{queues,[]},{port_no,10}]}]}]}, + {switch,6, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:06"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,12,[{queues,[]},{port_no,50}]}, + {port,14,[{queues,[]},{port_no,20}]}, + {port,16,[{queues,[]},{port_no,40}]}, + {port,19,[{queues,[]},{port_no,30}]}, + {port,31,[{queues,[]},{port_no,10}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,info}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/sys-nonlinear-4.config b/framework/src/onos/tools/test/topos/sys-nonlinear-4.config new file mode 100644 index 00000000..b843146a --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys-nonlinear-4.config @@ -0,0 +1,79 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"tap3"}]}, + {port,4,[{interface,"tap4"}]}]}, + {capable_switch_queues,[]}, + {optical_links,[{{1,20},{3,30}},{{3,31},{2,21}},{{1,22},{4,30}},{{4,31},{2,22}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,20}]}, + {port,7,[{queues,[]},{port_no,22}]}, + {port,3,[{queues,[]},{port_no,10}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,5,[{queues,[]},{port_no,30}]}, + {port,6,[{queues,[]},{port_no,31}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,21}]}, + {port,8,[{queues,[]},{port_no,22}]}, + {port,4,[{queues,[]},{port_no,11}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,9,[{queues,[]},{port_no,30}]}, + {port,10,[{queues,[]},{port_no,31}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,debug}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/sys.config b/framework/src/onos/tools/test/topos/sys.config new file mode 100644 index 00000000..2b999d39 --- /dev/null +++ b/framework/src/onos/tools/test/topos/sys.config @@ -0,0 +1,183 @@ +[{linc, + [{of_config,disabled}, + {software_desc,<<"LINC-OE OpenFlow Software Switch 1.1">>}, + {capable_switch_ports, + [{port,1,[{interface,"dummy"},{type,optical}]}, + {port,2,[{interface,"dummy"},{type,optical}]}, + {port,3,[{interface,"dummy"},{type,optical}]}, + {port,4,[{interface,"dummy"},{type,optical}]}, + {port,5,[{interface,"dummy"},{type,optical}]}, + {port,6,[{interface,"dummy"},{type,optical}]}, + {port,7,[{interface,"dummy"},{type,optical}]}, + {port,8,[{interface,"dummy"},{type,optical}]}, + {port,9,[{interface,"dummy"},{type,optical}]}, + {port,10,[{interface,"dummy"},{type,optical}]}, + {port,11,[{interface,"dummy"},{type,optical}]}, + {port,12,[{interface,"dummy"},{type,optical}]}, + {port,13,[{interface,"dummy"},{type,optical}]}, + {port,14,[{interface,"dummy"},{type,optical}]}, + {port,15,[{interface,"dummy"},{type,optical}]}, + {port,16,[{interface,"dummy"},{type,optical}]}, + {port,17,[{interface,"dummy"},{type,optical}]}, + {port,18,[{interface,"dummy"},{type,optical}]}, + {port,19,[{interface,"dummy"},{type,optical}]}, + {port,20,[{interface,"dummy"},{type,optical}]}, + {port,21,[{interface,"dummy"},{type,optical}]}, + {port,22,[{interface,"dummy"},{type,optical}]}, + {port,23,[{interface,"dummy"},{type,optical}]}, + {port,24,[{interface,"dummy"},{type,optical}]}, + {port,25,[{interface,"dummy"},{type,optical}]}, + {port,26,[{interface,"dummy"},{type,optical}]}, + {port,27,[{interface,"dummy"},{type,optical}]}, + {port,28,[{interface,"dummy"},{type,optical}]}, + {port,29,[{interface,"tap29"}]}, + {port,30,[{interface,"tap30"}]}, + {port,31,[{interface,"tap31"}]}, + {port,32,[{interface,"tap32"}]}, + {port,33,[{interface,"tap33"}]}, + {port,34,[{interface,"tap34"}]}]}, + {capable_switch_queues,[]}, + {optical_links, + [{{1,50},{2,30}}, + {{2,50},{3,30}}, + {{3,50},{4,50}}, + {{1,20},{5,50}}, + {{2,20},{5,20}}, + {{3,20},{6,50}}, + {{4,20},{6,20}}, + {{5,30},{6,40}}, + {{5,40},{7,50}}, + {{6,30},{8,50}}, + {{7,20},{8,30}}, + {{7,30},{9,50}}, + {{8,20},{10,50}}, + {{9,20},{10,20}}]}, + {logical_switches, + [{switch,1, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:01"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,1,[{queues,[]},{port_no,50}]}, + {port,7,[{queues,[]},{port_no,20}]}, + {port,29,[{queues,[]},{port_no,10}]}]}]}, + {switch,2, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:02"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,2,[{queues,[]},{port_no,30}]}, + {port,3,[{queues,[]},{port_no,50}]}, + {port,9,[{queues,[]},{port_no,20}]}]}]}, + {switch,3, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:03"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,4,[{queues,[]},{port_no,30}]}, + {port,5,[{queues,[]},{port_no,50}]}, + {port,11,[{queues,[]},{port_no,20}]}]}]}, + {switch,4, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:04"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,6,[{queues,[]},{port_no,50}]}, + {port,13,[{queues,[]},{port_no,20}]}, + {port,30,[{queues,[]},{port_no,10}]}]}]}, + {switch,5, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:05"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,8,[{queues,[]},{port_no,50}]}, + {port,10,[{queues,[]},{port_no,20}]}, + {port,15,[{queues,[]},{port_no,30}]}, + {port,17,[{queues,[]},{port_no,40}]}]}]}, + {switch,7, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:07"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,18,[{queues,[]},{port_no,50}]}, + {port,21,[{queues,[]},{port_no,20}]}, + {port,23,[{queues,[]},{port_no,30}]}, + {port,32,[{queues,[]},{port_no,10}]}]}]}, + {switch,8, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:08"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,20,[{queues,[]},{port_no,50}]}, + {port,22,[{queues,[]},{port_no,30}]}, + {port,25,[{queues,[]},{port_no,20}]}]}]}, + {switch,9, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:09"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,24,[{queues,[]},{port_no,50}]}, + {port,27,[{queues,[]},{port_no,20}]}, + {port,33,[{queues,[]},{port_no,10}]}]}]}, + {switch,10, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:0A"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,26,[{queues,[]},{port_no,50}]}, + {port,28,[{queues,[]},{port_no,20}]}, + {port,34,[{queues,[]},{port_no,10}]}]}]}, + {switch,6, + [{backend,linc_us4_oe}, + {datapath_id,"00:00:ff:ff:ff:ff:ff:06"}, + {controllers,[{"Switch0-Controller","10.1.8.147",6633,tcp}]}, + {controllers_listener,disabled}, + {queues_status,disabled}, + {ports, + [{port,12,[{queues,[]},{port_no,50}]}, + {port,14,[{queues,[]},{port_no,20}]}, + {port,16,[{queues,[]},{port_no,40}]}, + {port,19,[{queues,[]},{port_no,30}]}, + {port,31,[{queues,[]},{port_no,10}]}]}]}]}]}, + {epcap,[{verbose,false},{stats_interval,10}]}, + {enetconf, + [{capabilities, + [{base,{1,0}}, + {base,{1,1}}, + {startup,{1,0}}, + {'writable-running',{1,0}}]}, + {callback_module,linc_ofconfig}, + {sshd_ip,any}, + {sshd_port,1830}, + {sshd_user_passwords,[{"linc","linc"}]}]}, + {lager, + [{handlers, + [{lager_console_backend,info}, + {lager_file_backend, + [{"log/error.log",error,10485760,"$D0",5}, + {"log/console.log",info,10485760,"$D0",5}]}]}]}, + {sasl, + [{sasl_error_logger,{file,"log/sasl-error.log"}}, + {errlog_type,error}, + {error_logger_mf_dir,"log/sasl"}, + {error_logger_mf_maxbytes,10485760}, + {error_logger_mf_maxfiles,5}]}, + {sync,[{excluded_modules,[procket]}]}]. diff --git a/framework/src/onos/tools/test/topos/topo b/framework/src/onos/tools/test/topos/topo new file mode 100755 index 00000000..854de504 --- /dev/null +++ b/framework/src/onos/tools/test/topos/topo @@ -0,0 +1,10 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# Starts the specified mininet topology. +# ----------------------------------------------------------------------------- +cd $(dirname $0) + +topo=${1:-att-onos.py} + +[ -n "$1" ] && shift +sudo python $topo "$@" diff --git a/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py b/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py new file mode 100644 index 00000000..bb964e2b --- /dev/null +++ b/framework/src/onos/tools/test/topos/topo-200sw-linkalarm.py @@ -0,0 +1,20 @@ + +from mininet.topo import Topo + +class MyTopo( Topo ): + "10 'floating' switch topology" + + def __init__( self ): + # Initialize topology + Topo.__init__( self ) + + sw_list = [] + swC = self.addSwitch('sc', dpid = 'ffffffff00000001') + + for i in range(1, 201): + switch=self.addSwitch('s'+str(i), dpid = str(i).zfill(16)) + self.addLink(switch,swC) + + sw_list.append(switch) + +topos = { 'mytopo': ( lambda: MyTopo() ) } diff --git a/framework/src/onos/tools/test/topos/tower b/framework/src/onos/tools/test/topos/tower new file mode 100755 index 00000000..8244bae9 --- /dev/null +++ b/framework/src/onos/tools/test/topos/tower @@ -0,0 +1,2 @@ +#!/bin/bash +cd ~/topos && sudo mn --custom tower.py --topo tower --controller remote,${1:-192.168.56.101} --mac diff --git a/framework/src/onos/tools/test/topos/tower.py b/framework/src/onos/tools/test/topos/tower.py new file mode 100755 index 00000000..b75bfe40 --- /dev/null +++ b/framework/src/onos/tools/test/topos/tower.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +from mininet.topo import Topo +from mininet.cli import CLI +from mininet.net import Mininet +from mininet.node import RemoteController, OVSKernelSwitch +from mininet.log import setLogLevel + + +class TowerTopo( Topo ): + """Create a tower topology""" + + def build( self, k=4, h=6 ): + spines = [] + leaves = [] + hosts = [] + + # Create the two spine switches + spines.append(self.addSwitch('s1')) + spines.append(self.addSwitch('s2')) + + # Create two links between the spine switches + self.addLink(spines[0], spines[1]) + #TODO add second link between spines when multi-link topos are supported + #self.addLink(spines[0], spines[1]) + + # Now create the leaf switches, their hosts and connect them together + i = 1 + c = 0 + while i <= k: + leaves.append(self.addSwitch('s1%d' % i)) + for spine in spines: + self.addLink(leaves[i-1], spine) + + j = 1 + while j <= h: + hosts.append(self.addHost('h%d%d' % (i, j))) + self.addLink(hosts[c], leaves[i-1]) + j+=1 + c+=1 + + i+=1 + +topos = { 'tower': TowerTopo } + +def run(): + topo = TowerTopo() + net = Mininet( topo=topo, controller=RemoteController, autoSetMacs=True ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + setLogLevel( 'info' ) + run() diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/addresses.json b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/addresses.json new file mode 100644 index 00000000..9945e3f7 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/addresses.json @@ -0,0 +1,28 @@ +{ + "addresses" : [ + { + "dpid" : "00:00:00:00:00:00:00:a1", + "port" : "1", + "ips" : ["2001:1::101/48"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a2", + "port" : "1", + "ips" : ["2001:2::101/48"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a5", + "port" : "1", + "ips" : ["2001:3::101/48"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a6", + "port" : "1", + "ips" : ["2001:4::101/48"], + "mac" : "00:00:00:00:00:01" + } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/gui.json b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/gui.json new file mode 100644 index 00000000..588214b1 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/gui.json @@ -0,0 +1,9 @@ +{ + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:00000000000000a3/1", "ip": "2001:1::101, 2001:2::101, 2001:3::101, 2001:4::101", "annotations": { "type": "bgpSpeaker" } }, + { "mac": "00:00:00:00:01:01", "vlan": -1, "location": "of:00000000000000a1/1", "ip": "2001:1::1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:02:01", "vlan": -1, "location": "of:00000000000000a2/1", "ip": "2001:2::1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:03:01", "vlan": -1, "location": "of:00000000000000a5/1", "ip": "2001:3::1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:04:01", "vlan": -1, "location": "of:00000000000000a6/1", "ip": "2001:4::1", "annotations": { "type": "router" } } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga-sdn.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga-sdn.conf new file mode 100644 index 00000000..5d1fa9c1 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga-sdn.conf @@ -0,0 +1,45 @@ +! +hostname bgp +password sdnip +! +! +router bgp 65000 + bgp router-id 10.10.10.1 + timers bgp 3 9 + ! + neighbor 2001:1::1 remote-as 65001 + neighbor 2001:1::1 ebgp-multihop + neighbor 2001:1::1 timers connect 5 + neighbor 2001:1::1 advertisement-interval 5 + ! + neighbor 2001:2::1 remote-as 65002 + neighbor 2001:2::1 ebgp-multihop + neighbor 2001:2::1 timers connect 5 + neighbor 2001:2::1 advertisement-interval 5 + ! + neighbor 2001:3::1 remote-as 65003 + neighbor 2001:3::1 ebgp-multihop + neighbor 2001:3::1 timers connect 5 + neighbor 2001:3::1 advertisement-interval 5 + ! + neighbor 2001:4::1 remote-as 65004 + neighbor 2001:4::1 ebgp-multihop + neighbor 2001:4::1 timers connect 5 + neighbor 2001:4::1 advertisement-interval 5 + ! + ! ONOS + neighbor 10.10.10.2 remote-as 65000 + neighbor 10.10.10.2 port 2000 + neighbor 10.10.10.2 timers connect 5 + ! + ! IPv6 + ! + address-family ipv6 + neighbor 2001:1::1 activate + neighbor 2001:2::1 activate + neighbor 2001:3::1 activate + neighbor 2001:4::1 activate + neighbor 10.10.10.2 activate + exit-address-family +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga1.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga1.conf new file mode 100644 index 00000000..3c318e7f --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga1.conf @@ -0,0 +1,23 @@ +! BGP configuration for r1 +! +hostname r1 +password sdnip +! +router bgp 65001 + bgp router-id 10.0.1.1 + timers bgp 3 9 + neighbor 2001:1::101 remote-as 65000 + neighbor 2001:1::101 ebgp-multihop + neighbor 2001:1::101 advertisement-interval 5 + neighbor 2001:1::101 timers connect 5 + neighbor 2001:1::101 route-map nexthop out +! + address-family ipv6 + network 2001:101::/48 + neighbor 2001:1::101 activate + exit-address-family +! +route-map nexthop permit 10 + set ipv6 next-hop global 2001:1::1 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga2.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga2.conf new file mode 100644 index 00000000..4d377eb4 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga2.conf @@ -0,0 +1,23 @@ +! BGP configuration for r2 +! +hostname r2 +password sdnip +! +router bgp 65002 + bgp router-id 10.0.2.1 + timers bgp 3 9 + neighbor 2001:2::101 remote-as 65000 + neighbor 2001:2::101 ebgp-multihop + neighbor 2001:2::101 timers connect 5 + neighbor 2001:2::101 advertisement-interval 5 + neighbor 2001:2::101 route-map nexthop out +! + address-family ipv6 + network 2001:102::/48 + neighbor 2001:2::101 activate + exit-address-family +! +route-map nexthop permit 10 + set ipv6 next-hop global 2001:2::1 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga3.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga3.conf new file mode 100644 index 00000000..7cf7179c --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga3.conf @@ -0,0 +1,23 @@ +! BGP configuration for r3 +! +hostname r3 +password sdnip +! +router bgp 65003 + bgp router-id 10.0.3.1 + timers bgp 3 9 + neighbor 2001:3::101 remote-as 65000 + neighbor 2001:3::101 ebgp-multihop + neighbor 2001:3::101 timers connect 5 + neighbor 2001:3::101 advertisement-interval 5 + neighbor 2001:3::101 route-map nexthop out +! + address-family ipv6 + network 2001:103::/48 + neighbor 2001:3::101 activate + exit-address-family +! +route-map nexthop permit 10 + set ipv6 next-hop global 2001:3::1 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga4.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga4.conf new file mode 100644 index 00000000..32cfe243 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/quagga4.conf @@ -0,0 +1,23 @@ +! BGP configuration for r4 +! +hostname r4 +password sdnip +! +router bgp 65004 + bgp router-id 10.0.4.1 + timers bgp 3 9 + neighbor 2001:4::101 remote-as 65000 + neighbor 2001:4::101 ebgp-multihop + neighbor 2001:4::101 timers connect 5 + neighbor 2001:4::101 advertisement-interval 5 + neighbor 2001:4::101 route-map nexthop out +! + address-family ipv6 + !network 2001:104::/48 + neighbor 2001:4::101 activate + exit-address-family +! +route-map nexthop permit 10 + set ipv6 next-hop global 2001:4::1 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/sdnip.json b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/sdnip.json new file mode 100644 index 00000000..412fb5b8 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/sdnip.json @@ -0,0 +1,54 @@ +{ + "bgpPeers" : [ + { + "attachmentDpid" : "00:00:00:00:00:00:00:a1", + "attachmentPort" : "1", + "ipAddress" : "2001:1::1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a2", + "attachmentPort" : "1", + "ipAddress" : "2001:2::1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a5", + "attachmentPort" : "1", + "ipAddress" : "2001:3::1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a6", + "attachmentPort" : "1", + "ipAddress" : "2001:4::1" + } + ], + "bgpSpeakers" : [ + { + "name" : "bgp", + "attachmentDpid" : "00:00:00:00:00:00:00:a3", + "attachmentPort" : "1", + "macAddress" : "00:00:00:00:00:01", + "interfaceAddresses" : [ + { + "interfaceDpid" : "00:00:00:00:00:00:00:a1", + "interfacePort" : "1", + "ipAddress" : "2001:1::101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a2", + "interfacePort" : "1", + "ipAddress" : "2001:2::101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a5", + "interfacePort" : "1", + "ipAddress" : "2001:3::101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a6", + "interfacePort" : "1", + "ipAddress" : "2001:4::101" + } + ] + } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/zebra.conf b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/zebra.conf new file mode 100644 index 00000000..6a4ae953 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs-ipv6/zebra.conf @@ -0,0 +1,5 @@ +! Configuration for zebra (NB: it is the same for all routers) +! +hostname zebra +password sdnip +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/addresses.json b/framework/src/onos/tools/tutorials/sdnip/configs/addresses.json new file mode 100644 index 00000000..5b733212 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/addresses.json @@ -0,0 +1,28 @@ +{ + "addresses" : [ + { + "dpid" : "00:00:00:00:00:00:00:a1", + "port" : "1", + "ips" : ["10.0.1.101/24"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a2", + "port" : "1", + "ips" : ["10.0.2.101/24"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a5", + "port" : "1", + "ips" : ["10.0.3.101/24"], + "mac" : "00:00:00:00:00:01" + }, + { + "dpid" : "00:00:00:00:00:00:00:a6", + "port" : "1", + "ips" : ["10.0.4.101/24"], + "mac" : "00:00:00:00:00:01" + } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/gui.json b/framework/src/onos/tools/tutorials/sdnip/configs/gui.json new file mode 100644 index 00000000..fdc97575 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/gui.json @@ -0,0 +1,9 @@ +{ + "hosts" : [ + { "mac": "00:00:00:00:00:01", "vlan": -1, "location": "of:00000000000000a3/1", "ip": "10.0.1.101, 10.0.2.101, 10.0.3.101, 10.0.4.101", "annotations": { "type": "bgpSpeaker" } }, + { "mac": "00:00:00:00:01:01", "vlan": -1, "location": "of:00000000000000a1/1", "ip": "10.0.1.1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:02:01", "vlan": -1, "location": "of:00000000000000a2/1", "ip": "10.0.2.1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:03:01", "vlan": -1, "location": "of:00000000000000a5/1", "ip": "10.0.3.1", "annotations": { "type": "router" } }, + { "mac": "00:00:00:00:04:01", "vlan": -1, "location": "of:00000000000000a6/1", "ip": "10.0.4.1", "annotations": { "type": "router" } } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/quagga-sdn.conf b/framework/src/onos/tools/tutorials/sdnip/configs/quagga-sdn.conf new file mode 100644 index 00000000..983c96e6 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/quagga-sdn.conf @@ -0,0 +1,35 @@ +! +hostname bgp +password sdnip +! +! +router bgp 65000 + bgp router-id 10.10.10.1 + timers bgp 3 9 + ! + neighbor 10.0.1.1 remote-as 65001 + neighbor 10.0.1.1 ebgp-multihop + neighbor 10.0.1.1 timers connect 5 + neighbor 10.0.1.1 advertisement-interval 5 + ! + neighbor 10.0.2.1 remote-as 65002 + neighbor 10.0.2.1 ebgp-multihop + neighbor 10.0.2.1 timers connect 5 + neighbor 10.0.2.1 advertisement-interval 5 + ! + neighbor 10.0.3.1 remote-as 65003 + neighbor 10.0.3.1 ebgp-multihop + neighbor 10.0.3.1 timers connect 5 + neighbor 10.0.3.1 advertisement-interval 5 + ! + neighbor 10.0.4.1 remote-as 65004 + neighbor 10.0.4.1 ebgp-multihop + neighbor 10.0.4.1 timers connect 5 + neighbor 10.0.4.1 advertisement-interval 5 + ! + ! ONOS + neighbor 10.10.10.2 remote-as 65000 + neighbor 10.10.10.2 port 2000 + neighbor 10.10.10.2 timers connect 5 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/quagga1.conf b/framework/src/onos/tools/tutorials/sdnip/configs/quagga1.conf new file mode 100644 index 00000000..6e65c96d --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/quagga1.conf @@ -0,0 +1,15 @@ +! BGP configuration for r1 +! +hostname r1 +password sdnip +! +router bgp 65001 + bgp router-id 10.0.1.1 + timers bgp 3 9 + neighbor 10.0.1.101 remote-as 65000 + neighbor 10.0.1.101 ebgp-multihop + neighbor 10.0.1.101 timers connect 5 + neighbor 10.0.1.101 advertisement-interval 5 + network 192.168.1.0/24 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/quagga2.conf b/framework/src/onos/tools/tutorials/sdnip/configs/quagga2.conf new file mode 100644 index 00000000..8ab7205d --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/quagga2.conf @@ -0,0 +1,15 @@ +! BGP configuration for r2 +! +hostname r2 +password sdnip +! +router bgp 65002 + bgp router-id 10.0.2.1 + timers bgp 3 9 + neighbor 10.0.2.101 remote-as 65000 + neighbor 10.0.2.101 ebgp-multihop + neighbor 10.0.2.101 timers connect 5 + neighbor 10.0.2.101 advertisement-interval 5 + network 192.168.2.0/24 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/quagga3.conf b/framework/src/onos/tools/tutorials/sdnip/configs/quagga3.conf new file mode 100644 index 00000000..53d9c8a1 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/quagga3.conf @@ -0,0 +1,15 @@ +! BGP configuration for r3 +! +hostname r3 +password sdnip +! +router bgp 65003 + bgp router-id 10.0.3.1 + timers bgp 3 9 + neighbor 10.0.3.101 remote-as 65000 + neighbor 10.0.3.101 ebgp-multihop + neighbor 10.0.3.101 timers connect 5 + neighbor 10.0.3.101 advertisement-interval 5 + network 192.168.3.0/24 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/quagga4.conf b/framework/src/onos/tools/tutorials/sdnip/configs/quagga4.conf new file mode 100644 index 00000000..809d5005 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/quagga4.conf @@ -0,0 +1,15 @@ +! BGP configuration for r4 +! +hostname r4 +password sdnip +! +router bgp 65004 + bgp router-id 10.0.4.1 + timers bgp 3 9 + neighbor 10.0.4.101 remote-as 65000 + neighbor 10.0.4.101 ebgp-multihop + neighbor 10.0.4.101 timers connect 5 + neighbor 10.0.4.101 advertisement-interval 5 + !network 192.168.4.0/24 +! +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/sdnip.json b/framework/src/onos/tools/tutorials/sdnip/configs/sdnip.json new file mode 100644 index 00000000..dde8ea77 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/sdnip.json @@ -0,0 +1,54 @@ +{ + "bgpPeers" : [ + { + "attachmentDpid" : "00:00:00:00:00:00:00:a1", + "attachmentPort" : "1", + "ipAddress" : "10.0.1.1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a2", + "attachmentPort" : "1", + "ipAddress" : "10.0.2.1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a5", + "attachmentPort" : "1", + "ipAddress" : "10.0.3.1" + }, + { + "attachmentDpid" : "00:00:00:00:00:00:00:a6", + "attachmentPort" : "1", + "ipAddress" : "10.0.4.1" + } + ], + "bgpSpeakers" : [ + { + "name" : "bgp", + "attachmentDpid" : "00:00:00:00:00:00:00:a3", + "attachmentPort" : "1", + "macAddress" : "00:00:00:00:00:01", + "interfaceAddresses" : [ + { + "interfaceDpid" : "00:00:00:00:00:00:00:a1", + "interfacePort" : "1", + "ipAddress" : "10.0.1.101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a2", + "interfacePort" : "1", + "ipAddress" : "10.0.2.101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a5", + "interfacePort" : "1", + "ipAddress" : "10.0.3.101" + }, + { + "interfaceDpid" : "00:00:00:00:00:00:00:a6", + "interfacePort" : "1", + "ipAddress" : "10.0.4.101" + } + ] + } + ] +} diff --git a/framework/src/onos/tools/tutorials/sdnip/configs/zebra.conf b/framework/src/onos/tools/tutorials/sdnip/configs/zebra.conf new file mode 100644 index 00000000..6a4ae953 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/configs/zebra.conf @@ -0,0 +1,5 @@ +! Configuration for zebra (NB: it is the same for all routers) +! +hostname zebra +password sdnip +log stdout diff --git a/framework/src/onos/tools/tutorials/sdnip/tutorial.py b/framework/src/onos/tools/tutorials/sdnip/tutorial.py new file mode 100755 index 00000000..4f6d6bd1 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/tutorial.py @@ -0,0 +1,140 @@ +#!/usr/bin/python + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info, debug +from mininet.node import Host, RemoteController + +QUAGGA_DIR = '/usr/lib/quagga' +# Must exist and be owned by quagga user (quagga:quagga by default on Ubuntu) +QUAGGA_RUN_DIR = '/var/run/quagga' +CONFIG_DIR = 'configs' + +class SdnIpHost(Host): + def __init__(self, name, ip, route, *args, **kwargs): + Host.__init__(self, name, ip=ip, *args, **kwargs) + + self.route = route + + def config(self, **kwargs): + Host.config(self, **kwargs) + + debug("configuring route %s" % self.route) + + self.cmd('ip route add default via %s' % self.route) + +class Router(Host): + def __init__(self, name, quaggaConfFile, zebraConfFile, intfDict, *args, **kwargs): + Host.__init__(self, name, *args, **kwargs) + + self.quaggaConfFile = quaggaConfFile + self.zebraConfFile = zebraConfFile + self.intfDict = intfDict + + def config(self, **kwargs): + Host.config(self, **kwargs) + self.cmd('sysctl net.ipv4.ip_forward=1') + + for intf, attrs in self.intfDict.items(): + self.cmd('ip addr flush dev %s' % intf) + if 'mac' in attrs: + self.cmd('ip link set %s down' % intf) + self.cmd('ip link set %s address %s' % (intf, attrs['mac'])) + self.cmd('ip link set %s up ' % intf) + for addr in attrs['ipAddrs']: + self.cmd('ip addr add %s dev %s' % (addr, intf)) + + self.cmd('/usr/lib/quagga/zebra -d -f %s -z %s/zebra%s.api -i %s/zebra%s.pid' % (self.zebraConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name)) + self.cmd('/usr/lib/quagga/bgpd -d -f %s -z %s/zebra%s.api -i %s/bgpd%s.pid' % (self.quaggaConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name)) + + + def terminate(self): + self.cmd("ps ax | egrep 'bgpd%s.pid|zebra%s.pid' | awk '{print $1}' | xargs kill" % (self.name, self.name)) + + Host.terminate(self) + + +class SdnIpTopo( Topo ): + "SDN-IP tutorial topology" + + def build( self ): + s1 = self.addSwitch('s1', dpid='00000000000000a1') + s2 = self.addSwitch('s2', dpid='00000000000000a2') + s3 = self.addSwitch('s3', dpid='00000000000000a3') + s4 = self.addSwitch('s4', dpid='00000000000000a4') + s5 = self.addSwitch('s5', dpid='00000000000000a5') + s6 = self.addSwitch('s6', dpid='00000000000000a6') + + zebraConf = '%s/zebra.conf' % CONFIG_DIR + + # Switches we want to attach our routers to, in the correct order + attachmentSwitches = [s1, s2, s5, s6] + + for i in range(1, 4+1): + name = 'r%s' % i + + eth0 = { 'mac' : '00:00:00:00:0%s:01' % i, + 'ipAddrs' : ['10.0.%s.1/24' % i] } + eth1 = { 'ipAddrs' : ['192.168.%s.254/24' % i] } + intfs = { '%s-eth0' % name : eth0, + '%s-eth1' % name : eth1 } + + quaggaConf = '%s/quagga%s.conf' % (CONFIG_DIR, i) + + router = self.addHost(name, cls=Router, quaggaConfFile=quaggaConf, + zebraConfFile=zebraConf, intfDict=intfs) + + host = self.addHost('h%s' % i, cls=SdnIpHost, + ip='192.168.%s.1/24' % i, + route='192.168.%s.254' % i) + + self.addLink(router, attachmentSwitches[i-1]) + self.addLink(router, host) + + # Set up the internal BGP speaker + bgpEth0 = { 'mac':'00:00:00:00:00:01', + 'ipAddrs' : ['10.0.1.101/24', + '10.0.2.101/24', + '10.0.3.101/24', + '10.0.4.101/24',] } + bgpEth1 = { 'ipAddrs' : ['10.10.10.1/24'] } + bgpIntfs = { 'bgp-eth0' : bgpEth0, + 'bgp-eth1' : bgpEth1 } + + bgp = self.addHost( "bgp", cls=Router, + quaggaConfFile = '%s/quagga-sdn.conf' % CONFIG_DIR, + zebraConfFile = zebraConf, + intfDict=bgpIntfs ) + + self.addLink( bgp, s3 ) + + # Connect BGP speaker to the root namespace so it can peer with ONOS + root = self.addHost( 'root', inNamespace=False, ip='10.10.10.2/24' ) + self.addLink( root, bgp ) + + + # Wire up the switches in the topology + self.addLink( s1, s2 ) + self.addLink( s1, s3 ) + self.addLink( s2, s4 ) + self.addLink( s3, s4 ) + self.addLink( s3, s5 ) + self.addLink( s4, s6 ) + self.addLink( s5, s6 ) + +topos = { 'sdnip' : SdnIpTopo } + +if __name__ == '__main__': + setLogLevel('debug') + topo = SDNTopo() + + net = Mininet(topo=topo, controller=RemoteController) + + net.start() + + CLI(net) + + net.stop() + + info("done\n") diff --git a/framework/src/onos/tools/tutorials/sdnip/tutorial_ipv6.py b/framework/src/onos/tools/tutorials/sdnip/tutorial_ipv6.py new file mode 100755 index 00000000..9fc4f3f4 --- /dev/null +++ b/framework/src/onos/tools/tutorials/sdnip/tutorial_ipv6.py @@ -0,0 +1,152 @@ +#!/usr/bin/python + +from mininet.topo import Topo +from mininet.net import Mininet +from mininet.cli import CLI +from mininet.log import setLogLevel, info, debug +from mininet.node import Host, RemoteController, OVSSwitch + +QUAGGA_DIR = '/usr/lib/quagga' +# Must exist and be owned by quagga user (quagga:quagga by default on Ubuntu) +QUAGGA_RUN_DIR = '/var/run/quagga' +CONFIG_DIR = 'configs-ipv6' + +class SdnIpHost(Host): + def __init__(self, name, ip, route, *args, **kwargs): + Host.__init__(self, name, ip=ip, *args, **kwargs) + + self.name = name + self.ip = ip + self.route = route + + def config(self, **kwargs): + Host.config(self, **kwargs) + + debug("configuring route %s" % self.route) + + self.cmd('ip addr add %s dev %s-eth0' % (self.ip, self.name)) + self.cmd('ip route add default via %s' % self.route) + +class Router(Host): + def __init__(self, name, quaggaConfFile, zebraConfFile, intfDict, *args, **kwargs): + Host.__init__(self, name, *args, **kwargs) + + self.quaggaConfFile = quaggaConfFile + self.zebraConfFile = zebraConfFile + self.intfDict = intfDict + + def config(self, **kwargs): + Host.config(self, **kwargs) + self.cmd('sysctl net.ipv4.ip_forward=1') + self.cmd('sysctl net.ipv6.conf.all.forwarding=1') + + for intf, attrs in self.intfDict.items(): + self.cmd('ip addr flush dev %s' % intf) + if 'mac' in attrs: + self.cmd('ip link set %s down' % intf) + self.cmd('ip link set %s address %s' % (intf, attrs['mac'])) + self.cmd('ip link set %s up ' % intf) + for addr in attrs['ipAddrs']: + self.cmd('ip addr add %s dev %s' % (addr, intf)) + + self.cmd('/usr/lib/quagga/zebra -d -f %s -z %s/zebra%s.api -i %s/zebra%s.pid' % (self.zebraConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name)) + self.cmd('/usr/lib/quagga/bgpd -d -f %s -z %s/zebra%s.api -i %s/bgpd%s.pid' % (self.quaggaConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name)) + + + def terminate(self): + self.cmd("ps ax | egrep 'bgpd%s.pid|zebra%s.pid' | awk '{print $1}' | xargs kill" % (self.name, self.name)) + + Host.terminate(self) + +class SdnSwitch(OVSSwitch): + def __init__(self, name, dpid, *args, **kwargs): + OVSSwitch.__init__(self, name, dpid=dpid, *args, **kwargs) + + def start(self, controllers): + OVSSwitch.start(self, controllers) + self.cmd("ovs-vsctl set Bridge %s protocols=OpenFlow13" % self.name) + + +class SdnIpTopo( Topo ): + "SDN-IP tutorial topology" + + def build( self ): + s1 = self.addSwitch('s1', cls=SdnSwitch, dpid='00000000000000a1') + s2 = self.addSwitch('s2', cls=SdnSwitch, dpid='00000000000000a2') + s3 = self.addSwitch('s3', cls=SdnSwitch, dpid='00000000000000a3') + s4 = self.addSwitch('s4', cls=SdnSwitch, dpid='00000000000000a4') + s5 = self.addSwitch('s5', cls=SdnSwitch, dpid='00000000000000a5') + s6 = self.addSwitch('s6', cls=SdnSwitch, dpid='00000000000000a6') + + zebraConf = '%s/zebra.conf' % CONFIG_DIR + + # Switches we want to attach our routers to, in the correct order + attachmentSwitches = [s1, s2, s5, s6] + + for i in range(1, 4+1): + name = 'r%s' % i + + eth0 = { 'mac' : '00:00:00:00:0%s:01' % i, + 'ipAddrs' : ['2001:%s::1/48' % i] } + eth1 = { 'ipAddrs' : ['2001:10%s::101/48' % i] } + intfs = { '%s-eth0' % name : eth0, + '%s-eth1' % name : eth1 } + + quaggaConf = '%s/quagga%s.conf' % (CONFIG_DIR, i) + + router = self.addHost(name, cls=Router, quaggaConfFile=quaggaConf, + zebraConfFile=zebraConf, intfDict=intfs) + + host = self.addHost('h%s' % i, cls=SdnIpHost, + ip='2001:10%s::1/48' % i, + route='2001:10%s::101' % i) + + self.addLink(router, attachmentSwitches[i-1]) + self.addLink(router, host) + + # Set up the internal BGP speaker + bgpEth0 = { 'mac':'00:00:00:00:00:01', + 'ipAddrs' : ['2001:1::101/48', + '2001:2::101/48', + '2001:3::101/48', + '2001:4::101/48',] } + bgpEth1 = { 'ipAddrs' : ['10.10.10.1/24'] } + bgpIntfs = { 'bgp-eth0' : bgpEth0, + 'bgp-eth1' : bgpEth1 } + + bgp = self.addHost( "bgp", cls=Router, + quaggaConfFile = '%s/quagga-sdn.conf' % CONFIG_DIR, + zebraConfFile = zebraConf, + intfDict=bgpIntfs ) + + self.addLink( bgp, s3 ) + + # Connect BGP speaker to the root namespace so it can peer with ONOS + root = self.addHost( 'root', inNamespace=False, ip='10.10.10.2/24' ) + self.addLink( root, bgp ) + + + # Wire up the switches in the topology + self.addLink( s1, s2 ) + self.addLink( s1, s3 ) + self.addLink( s2, s4 ) + self.addLink( s3, s4 ) + self.addLink( s3, s5 ) + self.addLink( s4, s6 ) + self.addLink( s5, s6 ) + +topos = { 'sdnip' : SdnIpTopo } + +if __name__ == '__main__': + setLogLevel('debug') + topo = SdnIpTopo() + + net = Mininet(topo=topo, controller=RemoteController) + + net.start() + + CLI(net) + + net.stop() + + info("done\n") |