From fbd8f49cb9d5597029e6a3e39401745b5e96335c Mon Sep 17 00:00:00 2001 From: mesaj Date: Tue, 10 Jun 2025 17:08:07 +0200 Subject: [PATCH] Move Dockerfile from devops to the repo, base image Alpine Linux Change-Id: Id7cbb0c5bcbae9c523455994ffbeb2e743ecd563 Signed-off-by: mesaj Signed-off-by: garciadeblas --- Dockerfile.production | 176 ++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 - scripts/start.sh | 144 ++++++++++++++++++++++++++++++++++ 3 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 Dockerfile.production create mode 100755 scripts/start.sh diff --git a/Dockerfile.production b/Dockerfile.production new file mode 100644 index 00000000..495004e1 --- /dev/null +++ b/Dockerfile.production @@ -0,0 +1,176 @@ +# syntax=docker/dockerfile:1 +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# 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. +####################################################################################### + + +###################### +# Stage 1: Base Stage# +###################### + +FROM python:3.10-alpine AS base + +# RUN apk add --no-cache \ +# libgcc \ +# libstdc++ + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + + +######################################################################################################################################################################### + +######################## +# Stage 2: Build Stage # +######################## + +FROM base AS build + +# Install required system packages +RUN apk add --no-cache \ + build-base \ + git \ + patch \ + curl \ + zlib-dev \ + cdrkit \ + linux-headers \ + openssl \ + openssl-dev \ + libffi-dev \ + libmagic \ + cargo \ + rust \ + musl-dev \ + bash \ + openssh-client + +# Verify git installation +RUN git --version + +WORKDIR /app/ro + +# Isolate dependencies in a venv +RUN python -m venv /app/ro/.venv +ENV PATH="/app/ro/.venv/bin:$PATH" + +ARG COMMON_GERRIT_REFSPEC=master +ARG IM_GERRIT_REFSPEC=master + +# Install build tools +RUN pip install -U pip setuptools wheel build + +RUN test -x /app/ro/.venv/bin/python && /app/ro/.venv/bin/python -c "import sys; print(sys.prefix)" + +# Install OSM dependency modules + +RUN --mount=type=cache,target=/root/.cache/pip \ + git clone --filter=blob:none --tags https://osm.etsi.org/gerrit/osm/common.git /tmp/osm-common && \ + cd /tmp/osm-common && \ + git fetch origin ${COMMON_GERRIT_REFSPEC} && \ + git checkout FETCH_HEAD && \ + cd - && \ + pip install -r /tmp/osm-common/requirements.txt && \ + pip install /tmp/osm-common + +COPY requirements.txt ./ + +# Install py-radix from source with a one-line patch (no build isolation) +RUN --mount=type=cache,target=/root/.cache/pip \ + # py-radix is installed as dependency of the ipconflict package + # the installation is a bit special as it is not fully compatible with Alpine library versions + # similar issue reported here: https://github.com/mjschultz/py-radix/issues/70 + git clone --filter=blob:none https://github.com/mjschultz/py-radix.git /tmp/py-radix && \ + sed -i 's/from setuptools\.dist import Version/from packaging.version import Version/' /tmp/py-radix/setup.py && \ + pip install --no-build-isolation /tmp/py-radix && \ + pip install -r requirements.txt + +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install git+https://github.com/mjschultz/py-radix.git && \ + pip install -r requirements.txt + +COPY . . + +RUN for component in common RO-plugin NG-RO RO-VIM-* RO-SDN-*; do \ + if [ -d "$component" ]; then \ + python -m build $component && \ + pip install $component/dist/*.whl; \ + fi; \ + done + + +################################################################################################################################################################ + +######################## +# Stage 3: Final Stage # +######################## + +FROM base AS final +WORKDIR /app + +RUN apk add --no-cache \ + cdrkit \ + git \ + curl \ + libmagic \ + bash + +RUN addgroup -g 1000 appuser && \ + adduser -D -G appuser -u 1000 appuser -h /app appuser && \ + mkdir -p /app/storage/kafka && \ + mkdir -p /app/log && \ + chown -R appuser:appuser /app + +USER appuser:appuser + +ENV VIRTUAL_ENV=/app/.venv \ + PATH="/app/.venv/bin:$PATH" + +COPY --from=build --chown=appuser:appuser /app/ro/ /app/ + +EXPOSE 9090 + +# Database configuration +ENV RO_DB_HOST="" \ + RO_DB_OVIM_HOST="" \ + RO_DB_ROOT_PASSWORD="" \ + RO_DB_OVIM_ROOT_PASSWORD="" \ + RO_DB_USER=mano \ + RO_DB_OVIM_USER=mano \ + RO_DB_PASSWORD=manopw \ + RO_DB_OVIM_PASSWORD=manopw \ + RO_DB_PORT=3306 \ + RO_DB_OVIM_PORT=3306 \ + RO_DB_NAME=mano_db \ + RO_DB_OVIM_NAME=mano_vim_db \ + OPENMANO_TENANT=osm + +# Application configuration +ENV OSMRO_DATABASE_DRIVER=mongo \ + OSMRO_DATABASE_URI=mongodb://mongo:27017 \ + OSMRO_MESSAGE_DRIVER=kafka \ + OSMRO_MESSAGE_HOST=kafka \ + OSMRO_MESSAGE_PORT=9092 \ + OSMRO_LOG_LEVEL=INFO + +# Expose ports and volumes +VOLUME /var/log/osm + +# Set user and entrypoint +USER appuser +CMD ["python", "-u", "-m", "osm_ng_ro.ro_main"] + diff --git a/requirements.txt b/requirements.txt index 345f149e..0813e3f6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -313,8 +313,6 @@ psutil==7.1.0 # via # openstacksdk # oslo-utils -py-radix==0.10.0 - # via ipconflict pyasn1==0.6.1 # via # pyasn1-modules diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 00000000..daf65944 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,144 @@ +#!/bin/bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# 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. +####################################################################################### + + +[ -z "$RO_DB_OVIM_HOST" ] && export RO_DB_OVIM_HOST="$RO_DB_HOST" +[ -z "$RO_DB_OVIM_ROOT_PASSWORD" ] && export RO_DB_OVIM_ROOT_PASSWORD="$RO_DB_ROOT_PASSWORD" + +function is_db_created() { + db_host=$1 + db_port=$2 + db_user=$3 + db_pswd=$4 + db_name=$5 + + RESULT=`mysqlshow -h"$db_host" -P"$db_port" -u"$db_user" -p"$db_pswd" | grep -v Wildcard | grep -o $db_name` + if [ "$RESULT" == "$db_name" ]; then + + RESULT=`mysqlshow -h"$db_host" -P"$db_port" -u"$db_user" -p"$db_pswd" "$db_name" | grep -v Wildcard | grep schema_version` + #TODO validate version + if [ -n "$RESULT" ]; then + echo " DB $db_name exists and inited" + return 0 + else + echo " DB $db_name exists BUT not inited" + return 1 + fi + fi + echo " DB $db_name does not exist" + return 1 +} + +function configure(){ + #Database parameters + #db_host: localhost + #db_user: mano + #db_passwd: manopw + #db_name: mano_db + # Database ovim parameters + #db_ovim_host: localhost # by default localhost + #db_ovim_user: mano # DB user + #db_ovim_passwd: manopw # DB password + #db_ovim_name: mano_vim_db # Name of the OVIM MANO DB + + + sed -i "s/^db_host:.*/db_host: $RO_DB_HOST/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_user:.*/db_user: $RO_DB_USER/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_passwd:.*/db_passwd: $RO_DB_PASSWORD/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_name:.*/db_name: $RO_DB_NAME/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_ovim_host:.*/db_ovim_host: $RO_DB_OVIM_HOST/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_ovim_user:.*/db_ovim_user: $RO_DB_OVIM_USER/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_ovim_passwd:.*/db_ovim_passwd: $RO_DB_OVIM_PASSWORD/" /etc/osm/openmanod.cfg || return 1 + sed -i "s/^db_ovim_name:.*/db_ovim_name: $RO_DB_OVIM_NAME/" /etc/osm/openmanod.cfg || return 1 + return 0 +} + +max_attempts=120 +function wait_db(){ + db_host=$1 + db_port=$2 + attempt=0 + echo "Wait until $max_attempts seconds for MySQL mano Server ${db_host}:${db_port} " + while ! mysqladmin ping -h"$db_host" -P"$db_port" --silent; do + #wait 120 sec + if [ $attempt -ge $max_attempts ]; then + echo + echo "Can not connect to database ${db_host}:${db_port} during $max_attempts sec" + return 1 + fi + attempt=$[$attempt+1] + echo -n "." + sleep 1 + done + return 0 +} + + +echo "1/4 Apply config" +configure || exit 1 + + +echo "2/4 Wait for db up" +wait_db "$RO_DB_HOST" "$RO_DB_PORT" || exit 1 +[ "$RO_DB_OVIM_HOST" = "$RO_DB_HOST" ] || wait_db "$RO_DB_OVIM_HOST" "$RO_DB_OVIM_PORT" || exit 1 + + +echo "3/4 Init database" +RO_PATH=`python -c 'import osm_ro; print(osm_ro.__path__[0])'` +echo "RO_PATH: $RO_PATH" +if ! is_db_created "$RO_DB_HOST" "$RO_DB_PORT" "$RO_DB_USER" "$RO_DB_PASSWORD" "$RO_DB_NAME" +then + if [ -n "$RO_DB_ROOT_PASSWORD" ] ; then + mysqladmin -h"$RO_DB_HOST" -uroot -p"$RO_DB_ROOT_PASSWORD" create "$RO_DB_NAME" + echo "CREATE USER '${RO_DB_USER}'@'%' IDENTIFIED BY '${RO_DB_PASSWORD}';" | + mysql -h"$RO_DB_HOST" -uroot -p"$RO_DB_ROOT_PASSWORD" || echo "user ${RO_DB_USER} already created?" + echo "GRANT ALL PRIVILEGES ON ${RO_DB_NAME}.* TO '${RO_DB_USER}'@'%';" | + mysql -h"$RO_DB_HOST" -uroot -p"$RO_DB_ROOT_PASSWORD" || echo "user ${RO_DB_USER} already granted?" + fi + ${RO_PATH}/database_utils/init_mano_db.sh -u "$RO_DB_USER" -p "$RO_DB_PASSWORD" -h "$RO_DB_HOST" \ + -P "${RO_DB_PORT}" -d "${RO_DB_NAME}" || exit 1 +else + echo " migrage database version" + ${RO_PATH}/database_utils/migrate_mano_db.sh -u "$RO_DB_USER" -p "$RO_DB_PASSWORD" -h "$RO_DB_HOST" \ + -P "$RO_DB_PORT" -d "$RO_DB_NAME" +fi + +OVIM_PATH=`python -c 'import lib_osm_openvim; print(lib_osm_openvim.__path__[0])'` +echo "OVIM_PATH: $OVIM_PATH" +if ! is_db_created "$RO_DB_OVIM_HOST" "$RO_DB_OVIM_PORT" "$RO_DB_OVIM_USER" "$RO_DB_OVIM_PASSWORD" "$RO_DB_OVIM_NAME" +then + if [ -n "$RO_DB_OVIM_ROOT_PASSWORD" ] ; then + mysqladmin -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" create "$RO_DB_OVIM_NAME" + echo "CREATE USER '${RO_DB_OVIM_USER}'@'%' IDENTIFIED BY '${RO_DB_OVIM_PASSWORD}';" | + mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || + echo "user ${RO_DB_OVIM_USER} already created?" + echo "GRANT ALL PRIVILEGES ON ${RO_DB_OVIM_NAME}.* TO '${RO_DB_OVIM_USER}'@'%';" | + mysql -h"$RO_DB_OVIM_HOST" -uroot -p"$RO_DB_OVIM_ROOT_PASSWORD" || + echo "user ${RO_DB_OVIM_USER} already granted?" + fi + ${OVIM_PATH}/database_utils/init_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST" \ + -P "${RO_DB_OVIM_PORT}" -d "${RO_DB_OVIM_NAME}" || exit 1 +else + echo " migrage database version" + ${OVIM_PATH}/database_utils/migrate_vim_db.sh -u "$RO_DB_OVIM_USER" -p "$RO_DB_OVIM_PASSWORD" -h "$RO_DB_OVIM_HOST"\ + -P "$RO_DB_OVIM_PORT" -d "$RO_DB_OVIM_NAME" +fi + + +echo "4/4 Try to start" +/usr/bin/openmanod -c /etc/osm/openmanod.cfg --log-file=/var/log/osm/openmano.log --create-tenant=osm -- 2.25.1