[AETHER-1265] Integrate Java profiler in TOST env

- Adds a dockerfile to build ONOS image with profiler agent enabled
- Prevents the overriding of the JAVA_OPTS when using the profiler
- Deploy profiler also in the atomix nodes when using stc

Change-Id: I00d5091428083f44360989c701350b7fead66038
diff --git a/tools/dev/Dockerfile-yourkit b/tools/dev/Dockerfile-yourkit
new file mode 100644
index 0000000..d54460e
--- /dev/null
+++ b/tools/dev/Dockerfile-yourkit
@@ -0,0 +1,116 @@
+# Copyright 2021-present Open Networking Foundation
+#
+# 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.
+
+# With this dockerfile you can build a ONOS Docker container
+# with YourKit profiler agent enabled
+
+ARG JOBS=2
+ARG PROFILE=default
+ARG TAG=11.0.8-11.41.23
+ARG JAVA_PATH=/usr/lib/jvm/zulu11-ca-amd64
+
+# First stage is the build environment.
+# zulu-openjdk images are based on Ubuntu.
+FROM azul/zulu-openjdk:${TAG} as builder
+
+# Define the profiler version to be used
+ARG ONOS_YOURKIT
+
+ENV BUILD_DEPS \
+    ca-certificates \
+    zip \
+    python \
+    python3 \
+    git \
+    bzip2 \
+    build-essential \
+    curl \
+    unzip
+RUN apt-get update && apt-get install -y ${BUILD_DEPS}
+
+# Install Bazelisk, which will download the version of bazel specified in
+# .bazelversion
+RUN curl -L -o bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.5.0/bazelisk-linux-amd64
+RUN chmod +x bazelisk && mv bazelisk /usr/bin
+
+# Build-stage environment variables
+ENV ONOS_ROOT /src/onos
+ENV BUILD_NUMBER docker
+ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
+
+# Copy in the sources
+COPY . ${ONOS_ROOT}
+WORKDIR ${ONOS_ROOT}
+
+# Build ONOS using the JDK pre-installed in the base image, instead of the
+# Bazel-provided remote one. By doing wo we make sure to build with the most
+# updated JDK, including bug and security fixes, independently of the Bazel
+# version.
+ARG JOBS
+ARG JAVA_PATH
+ARG PROFILE
+RUN bazelisk build onos \
+    --jobs ${JOBS} \
+    --verbose_failures \
+    --javabase=@bazel_tools//tools/jdk:absolute_javabase \
+    --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
+    --define=ABSOLUTE_JAVABASE=${JAVA_PATH} \
+    --define profile=${PROFILE}
+
+# We extract the tar in the build environment to avoid having to put the tar in
+# the runtime stage. This saves a lot of space.
+RUN mkdir /output
+RUN tar -xf bazel-bin/onos.tar.gz -C /output --strip-components=1
+# Get yourkit profiler and extract in the ONOS temp folder
+RUN curl -L -o yourkit.zip https://www.yourkit.com/download/YourKit-JavaProfiler-$ONOS_YOURKIT.zip && \
+    unzip -o yourkit.zip && \
+    rm yourkit.zip && \
+    mv YourKit-JavaProfiler-$(echo $ONOS_YOURKIT | sed 's/\(.*\)-.*/\1/')/bin/linux-x86-64/libyjpagent.so /output/libyjpagent.so
+
+# Second and final stage is the runtime environment.
+FROM azul/zulu-openjdk:${TAG}
+
+LABEL org.label-schema.name="ONOS" \
+      org.label-schema.description="SDN Controller" \
+      org.label-schema.usage="http://wiki.onosproject.org" \
+      org.label-schema.url="http://onosproject.org" \
+      org.label-scheme.vendor="Open Networking Foundation" \
+      org.label-schema.schema-version="1.0" \
+      maintainer="onos-dev@onosproject.org"
+
+RUN apt-get update && apt-get install -y curl && \
+	rm -rf /var/lib/apt/lists/*
+
+# Install ONOS in /root/onos
+COPY --from=builder /output/ /root/onos/
+WORKDIR /root/onos
+
+# Set JAVA_HOME (by default not exported by zulu images)
+ARG JAVA_PATH
+ENV JAVA_HOME ${JAVA_PATH}
+# Set ONOS_YOURKIT to enable the profiler agent
+ENV ONOS_YOURKIT true
+
+# Ports
+# 6653 - OpenFlow
+# 6640 - OVSDB
+# 8181 - GUI
+# 8101 - ONOS CLI
+# 9876 - ONOS intra-cluster communication
+# 10001-10010 - YourKit profiler
+EXPOSE 6653 6640 8181 8101 9876 10001-10010
+
+# Run ONOS
+ENTRYPOINT ["./bin/onos-service"]
+CMD ["server"]
diff --git a/tools/package/bin/onos-service b/tools/package/bin/onos-service
index d465a0d..b0ef25f 100755
--- a/tools/package/bin/onos-service
+++ b/tools/package/bin/onos-service
@@ -10,15 +10,20 @@
 # Do modify the keystore location/password and truststore location/password accordingly
 #export JAVA_OPTS="${JAVA_OPTS:--Dio.atomix.enableNettyTLS=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}"
 
-export JAVA_OPTS=${JAVA_OPTS:--XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Dkaraf.log.console=INFO -Dds.lock.timeout.milliseconds=10000}
-
-set -e  # exit on error
-set -u  # exit on undefined variable
-
 # If ONOS_HOME is set, respect its value.
 # If ONOS_HOME is not set (e.g. in the init or service environment),
 # set it based on this script's path.
 ONOS_HOME=${ONOS_HOME:-$(cd $(dirname $0)/.. >/dev/null 2>&1 && pwd)}
+
+JAVA_OPTS="${JAVA_OPTS:--XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Dkaraf.log.console=INFO -Dds.lock.timeout.milliseconds=10000}"
+if [ ! -z "$ONOS_YOURKIT" ]; then
+  JAVA_OPTS+=" -agentpath:$ONOS_HOME/libyjpagent.so=listen=all"
+fi
+export JAVA_OPTS=${JAVA_OPTS}
+
+set -e  # exit on error
+set -u  # exit on undefined variable
+
 KARAF_ARGS=server
 SYS_APPS=drivers
 ONOS_APPS=${ONOS_APPS:-gui2}  # Activate GUI2 unless specific apps were named
diff --git a/tools/test/bin/atomix-install b/tools/test/bin/atomix-install
index b059e12..92ec60f 100755
--- a/tools/test/bin/atomix-install
+++ b/tools/test/bin/atomix-install
@@ -48,6 +48,15 @@
 
     sudo mkdir -p $ATOMIX_INSTALL_DIR && sudo chown ${ONOS_USER}:${ONOS_GROUP} $ATOMIX_INSTALL_DIR
     tar -xvf /tmp/atomix.tar.gz -C $ATOMIX_INSTALL_DIR
+
+    if [ ! -z "$ONOS_YOURKIT" ]; then
+        sudo apt-get install unzip
+        cd /tmp
+        wget -N https://www.yourkit.com/download/YourKit-JavaProfiler-${ONOS_YOURKIT}.zip
+        unzip -o YourKit-JavaProfiler-${ONOS_YOURKIT}.zip
+        rm YourKit-JavaProfiler-${ONOS_YOURKIT}.zip
+        mv /tmp/YourKit-JavaProfiler-$(echo $ONOS_YOURKIT | sed 's/\(.*\)-.*/\1/')/bin/linux-x86-64/libyjpagent.so $ATOMIX_INSTALL_DIR/libyjpagent.so
+    fi
 "
 
 # Configure the ONOS installation
diff --git a/tools/test/bin/atomix-service b/tools/test/bin/atomix-service
index 7b60d93..5910a8c 100755
--- a/tools/test/bin/atomix-service
+++ b/tools/test/bin/atomix-service
@@ -39,11 +39,19 @@
     nodes=$(find_node ${1:-$OCI})
 fi
 
+# Define the java options for atomix
+# FIXME atomix-agent already provides a gc algorithm. Once we fix atomix-agent we can allow this
+# JAVA_OPTS="${JAVA_OPTS:--XX:+UseG1GC -XX:MaxGCPauseMillis=200}"
+if [ ! -z "$ONOS_YOURKIT" ]; then
+    #JAVA_OPTS+=" -agentpath:$ATOMIX_INSTALL_DIR/libyjpagent.so=listen=all"
+    JAVA_OPTS="${JAVA_OPTS:--agentpath:$ATOMIX_INSTALL_DIR/libyjpagent.so=listen=all}"
+fi
+
 case $2 in
     start)
         # Execute the remote commands
         for node in $nodes; do
-            ssh $ONOS_USER@${node} "nohup $ATOMIX_INSTALL_DIR/bin/atomix-agent -c $ATOMIX_INSTALL_DIR/atomix.json >/dev/null 2>&1 &"
+            ssh $ONOS_USER@${node} "JAVA_OPTS=\"${JAVA_OPTS}\" nohup $ATOMIX_INSTALL_DIR/bin/atomix-agent -c $ATOMIX_INSTALL_DIR/atomix.json >/dev/null 2>&1 &"
         done
     ;;
     stop)
diff --git a/tools/test/bin/onos-install b/tools/test/bin/onos-install
index 391640c..df220e3 100755
--- a/tools/test/bin/onos-install
+++ b/tools/test/bin/onos-install
@@ -88,7 +88,7 @@
         unzip -o YourKit-JavaProfiler-${ONOS_YOURKIT}.zip
         rm YourKit-JavaProfiler-${ONOS_YOURKIT}.zip
         mv /tmp/YourKit-JavaProfiler-$(echo $ONOS_YOURKIT | sed 's/\(.*\)-.*/\1/')/bin/linux-x86-64/libyjpagent.so $ONOS_INSTALL_DIR/libyjpagent.so
-        echo -e 'export JAVA_OPTS="${JAVA_OPTS:--agentpath:$ONOS_INSTALL_DIR/libyjpagent.so}=listen=all"' >> $ONOS_INSTALL_DIR/options
+        echo -e 'export ONOS_YOURKIT=$ONOS_YOURKIT' >> $ONOS_INSTALL_DIR/options
     fi
 
     # Set up correct user to run onos-service