nymea-energy-plugin-nymea/docker-simulation.sh

271 lines
7.7 KiB
Bash
Executable File

#!/bin/bash -e
CURRENTDIR=$(pwd)
#------------------------------------------------------------------------------------------
function usage() {
cat <<EOF
Run the simulations in a docker container for playing around
OPTIONS:
-h, --help Show this message
Container OPTIONS:
--shell Start the shell within the simulation container
--delete-container Delete container before starting
--container-name [NAME] Append the given name to the default container name based on the system type for keeping builds separate if required.
EOF
}
# bash colors
BASH_GREEN="\e[1;32m"
BASH_RED="\e[1;31m"
BASH_YELLOW="\e[0;33m"
BASH_NORMAL="\e[0m"
COLORS=true
#------------------------------------------------------------------------------------------
function printGreen() {
if ${COLORS}; then
echo -e "${BASH_GREEN}[+] $1${BASH_NORMAL}"
else
echo -e "[+] $1"
fi
}
#------------------------------------------------------------------------------------------
function printYellow() {
if ${COLORS}; then
echo -e "${BASH_YELLOW}[+] $1${BASH_NORMAL}"
else
echo -e "[+] $1"
fi
}
#------------------------------------------------------------------------------------------
function printRed() {
if ${COLORS}; then
echo -e "${BASH_RED}[!] $1${BASH_NORMAL}"
else
echo -e "[!] $1"
fi
}
#------------------------------------------------------------------------------------------
function buildImage() {
printGreen "Build image ${IMAGE_NAME} "
docker build -t ${IMAGE_NAME} -f- . <<EOF
FROM debian:${DEBIAN_RELEASE}
ENV DEBIAN_FRONTEND noninteractive
ENV container docker
ENV LC_ALL C
RUN apt-get -y update
RUN apt-get -y install nano wget
RUN echo "deb http://repository.nymea.io/experimental ${DEBIAN_RELEASE} main" > /etc/apt/sources.list.d/nymea.list
RUN wget -O /etc/apt/trusted.gpg.d/nymea.gpg https://repository.nymea.io/nymea.gpg
RUN apt-get -y update
RUN apt-get -y install libnymea-dev libnymea-core-dev libnymea-tests-dev libnymea-energy-dev \
nymea-experience-plugin-energy libqt5websockets5-dev nymea-dev-tools:native \
qt5-qmake qtbase5-dev gnuplot build-essential
RUN apt-get -y clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN echo "alias ll='ls -la'" >> /etc/bash.bashrc
RUN mkdir /nymea-energy/
RUN mkdir /nymea-energy-source/
# Create the ssh entry point in order to have the correct ssh file within the container
# and start sleeping infinite. We want the container to run so we can start commands from the host
RUN echo '#!/bin/bash -e' > /bin/docker-entrypoint.sh && \
echo '' >> /bin/docker-entrypoint.sh && \
echo 'sleep infinity' >> /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
WORKDIR /nymea-energy/
EOF
}
function startContainer() {
printGreen "Starting container ${CONTAINER_NAME}"
docker start ${CONTAINER_NAME}
}
function executeContainer() {
COMMAND="$@"
set +e
docker exec -w /nymea-energy -u root --privileged ${CONTAINER_NAME} /bin/bash -e -o pipefail -c "$COMMAND"
BUILD_RESULT=$?
set -e
if [ ${BUILD_RESULT} -ne 0 ]; then
printRed "Build command finished with error. Keeping the container for inspection."
exit 1
fi
}
function launchContainer() {
printGreen "Creating container ${CONTAINER_NAME} from ${IMAGE_NAME}"
docker run -d --name "${CONTAINER_NAME}" --privileged \
--cap-add=ALL \
--volume /dev:/dev \
--volume /sys/fs/cgroup:/sys/fs/cgroup:ro \
--volume ${CURRENTDIR}:/nymea-energy-source/:ro \
${IMAGE_NAME}
}
function synchSourceInContainer() {
printGreen "Synchronize source in the container ..."
executeContainer "rsync -rlptD --delete --exclude 'build' --exclude 'output' /nymea-energy-source/ ."
executeContainer "ls -la"
}
#------------------------------------------------------------------------------------------
# Main
#------------------------------------------------------------------------------------------
KEEP_DATA=false
KEEP_CONTAINER=true
RUN_SHELL=false
RUN_DELETE_CONTAINER=false
CONTAINER_NAME_APPEND=""
DEBIAN_RELEASE=bookworm
while [ "$1" != "" ]; do
case $1 in
--delete-container )
RUN_DELETE_CONTAINER=true;;
--shell )
RUN_SHELL=true;;
--container-name )
CONTAINER_NAME_APPEND=$2
shift;;
-h | --help )
usage && exit 0;;
* )
usage && exit 1;;
esac
shift
done
if ! docker ps >/dev/null; then
printRed "Error connecting to docker:"
docker ps
exit 1
fi
IMAGE_NAME=nymea-energy
CONTAINER_NAME=${IMAGE_NAME}-simulation
if [ ! -z ${CONTAINER_NAME_APPEND} ]; then
CONTAINER_NAME=${IMAGE_NAME}-${CONTAINER_NAME_APPEND}-simulation
fi
# Verify image
IMAGE_EXISTS=false
if docker image ls | grep ${IMAGE_NAME} >/dev/null; then
printGreen "--> Image ${IMAGE_NAME} already created on this host."
IMAGE_EXISTS=true
else
printGreen "--> Image ${IMAGE_NAME} not found. Creating image first..."
buildImage
fi
# Verify container exists
CONTAINER_EXISTS=false
if [ "$(docker ps -a --filter name="${CONTAINER_NAME}" -q)" != "" ]; then
printGreen "--> Container ${IMAGE_NAME} exists"
CONTAINER_EXISTS=true
else
printGreen "--> Container ${IMAGE_NAME} does not exist yet."
fi
# Verify container running
CONTAINER_RUNNING=false
if [ "$(docker ps --filter name="${CONTAINER_NAME}" -q)" != "" ]; then
printGreen "--> Container ${IMAGE_NAME} is up and running."
CONTAINER_RUNNING=true
else
printGreen "--> Container ${IMAGE_NAME} is not running."
fi
# Handle delete container request
if ${RUN_DELETE_CONTAINER}; then
if ${CONTAINER_EXISTS}; then
printGreen "Delete container ${CONTAINER_NAME}"
docker rm -fv "${CONTAINER_NAME}"
CONTAINER_RUNNING=false
CONTAINER_EXISTS=false
fi
fi
# Handle shell login into container
if ${RUN_SHELL}; then
if ${CONTAINER_EXISTS}; then
if ! ${CONTAINER_RUNNING}; then
startContainer
fi
else
launchContainer
synchSourceInContainer
fi
docker exec -it -w /nymea-energy -u root --privileged ${CONTAINER_NAME} /bin/bash
exit 0
fi
if ${CONTAINER_RUNNING}; then
printYellow "The simulation container ${CONTAINER_NAME} is running. Stopping it..."
docker stop ${CONTAINER_NAME}
fi
BUILD_COMMAND='if [ ! -d build ]; then mkdir -p build; fi ; cd build ; qmake .. ; make -j $(nproc) ; cd ./tests/auto/simulation/ ; pwd; ./nymea-energy-simulation -maxwarnings 0'
printGreen "Running build script with"
echo "${BUILD_COMMAND}"
# Run the build command inside the container
if ${CONTAINER_EXISTS}; then
startContainer
synchSourceInContainer
executeContainer "${BUILD_COMMAND}"
else
launchContainer
synchSourceInContainer
executeContainer "${BUILD_COMMAND}"
fi
printGreen "Copy simulation results from container..."
RESULTS_DIR=${CURRENTDIR}/results
if [ -d ${RESULTS_DIR} ]; then
printGreen "Clean up previouse results ..."
rm -rf ${RESULTS_DIR}
fi
mkdir -p ${RESULTS_DIR}
docker cp ${CONTAINER_NAME}:/nymea-energy/build/tests/auto/simulation/simulations/results/ ${CURRENTDIR}
printGreen "Stopping the container"
docker stop ${CONTAINER_NAME}
# Cleanup if required
if ! $KEEP_CONTAINER; then
printGreen "Delete container ${CONTAINER_NAME}"
docker rm -v "${CONTAINER_NAME}"
fi
printGreen "Simulation run finished successfully. Results can be found in ${RESULTS_DIR}"
ls -l ${RESULTS_DIR}