From 20ca6a6167805e5c78e1ca40777f4a22bfa47fab Mon Sep 17 00:00:00 2001 From: Stefan Dinescu Date: Tue, 23 Apr 2019 11:57:41 +0000 Subject: [PATCH] Container Openstackclient wrapper With openstackclients moving to a container, issuing openstack command to the application side would become difficult due to log "kubectl" commands and the random nature of pod names. This commit introduces a wrapper for the containerized client that automatically passes the desired command to the pod. This commit also introduces a wrapper for copying files dirrectly to clients container for commands that need filesystem access (for example creating images with "openstack image create"). We also alias the default openstack command to the containerized client. The platform openstack command is aliased to "platform-openstack". Change-Id: I7b204bb05381d38f4f25066561e001bb8247943b Signed-off-by: Stefan Dinescu Story: 2005312 Task: 30603 Depends-on: I58a5d511cf54dacc018bfb88848899b92a774087 --- .../platform-util/centos/platform-util.spec | 17 +++-- .../platform-util/scripts/openstack-pod-cp.sh | 67 +++++++++++++++++++ .../scripts/openstack-pod-exec.sh | 64 ++++++++++++++++++ .../platform-util/scripts/osc-profile.sh | 11 +++ 4 files changed, 155 insertions(+), 4 deletions(-) create mode 100755 utilities/platform-util/scripts/openstack-pod-cp.sh create mode 100755 utilities/platform-util/scripts/openstack-pod-exec.sh create mode 100644 utilities/platform-util/scripts/osc-profile.sh diff --git a/utilities/platform-util/centos/platform-util.spec b/utilities/platform-util/centos/platform-util.spec index b54116b49..dcd70b154 100644 --- a/utilities/platform-util/centos/platform-util.spec +++ b/utilities/platform-util/centos/platform-util.spec @@ -28,7 +28,8 @@ Platform utilities that don't get packaged on controller hosts %define local_bindir %{local_dir}/bin %define local_sbindir %{local_dir}/sbin %define pythonroot /usr/lib64/python2.7/site-packages -%define local_etc_initd %{_sysconfdir}/init.d +%define system_initd %{_sysconfdir}/init.d +%define system_profiled %{_sysconfdir}/profile.d %prep %setup @@ -53,9 +54,11 @@ install -d %{buildroot}%{local_bindir} install %{_buildsubdir}/scripts/cgcs_tc_setup.sh %{buildroot}%{local_bindir} install %{_buildsubdir}/scripts/remotelogging_tc_setup.sh %{buildroot}%{local_bindir} install %{_buildsubdir}/scripts/connectivity_test %{buildroot}%{local_bindir} +install %{_buildsubdir}/scripts/openstack-pod-exec.sh %{buildroot}%{local_bindir} +install %{_buildsubdir}/scripts/openstack-pod-cp.sh %{buildroot}%{local_bindir} -install -d %{buildroot}%{local_etc_initd} -install %{_buildsubdir}/scripts/log_functions.sh %{buildroot}%{local_etc_initd} +install -d %{buildroot}%{system_initd} +install %{_buildsubdir}/scripts/log_functions.sh %{buildroot}%{system_initd} install -d %{buildroot}%{local_sbindir} install -m 700 -P -D %{_buildsubdir}/scripts/patch-restart-mtce %{buildroot}%{local_sbindir} @@ -66,6 +69,9 @@ install -d %{buildroot}/etc/systemd/system install -m 644 -p -D %{_buildsubdir}/scripts/opt-platform.mount %{buildroot}/etc/systemd/system install -m 644 -p -D %{_buildsubdir}/scripts/opt-platform.service %{buildroot}/etc/systemd/system +install -d %{buildroot}%{system_profiled} +install -m 644 %{_buildsubdir}/scripts/osc-profile.sh %{buildroot}%{system_profiled} + # Mask the systemd ctrl-alt-delete.target, to disable reboot on ctrl-alt-del ln -sf /dev/null %{buildroot}/etc/systemd/system/ctrl-alt-del.target @@ -83,15 +89,18 @@ systemctl enable opt-platform.service %{local_bindir}/cgcs_tc_setup.sh %{local_bindir}/remotelogging_tc_setup.sh %{local_bindir}/connectivity_test +%{local_bindir}/openstack-pod-exec.sh +%{local_bindir}/openstack-pod-cp.sh %{local_sbindir}/patch-restart-mtce %{local_sbindir}/patch-restart-processes %{local_sbindir}/patch-restart-haproxy +%{system_profiled}/osc-profile.sh /etc/systemd/system/ctrl-alt-del.target %dir %{pythonroot}/platform_util %{pythonroot}/platform_util/* %dir %{pythonroot}/platform_util-%{version}.0-py2.7.egg-info %{pythonroot}/platform_util-%{version}.0-py2.7.egg-info/* -%{local_etc_initd}/log_functions.sh +%{system_initd}/log_functions.sh %files -n platform-util-noncontroller %defattr(-,root,root,-) diff --git a/utilities/platform-util/scripts/openstack-pod-cp.sh b/utilities/platform-util/scripts/openstack-pod-cp.sh new file mode 100755 index 000000000..de064d75e --- /dev/null +++ b/utilities/platform-util/scripts/openstack-pod-cp.sh @@ -0,0 +1,67 @@ +#! /bin/bash + +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CLIENT_IMAGE_NAME="openstack-clients" +NAMESPACE="openstack" +STATE="Running" +MOUNT_PATH="/scratch" +POD_NAME=$(kubectl -n ${NAMESPACE} get pods -o wide 2>&1 |grep ${CLIENT_IMAGE_NAME} |grep ${STATE} |awk '{print $1}') + +declare -A levels=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3) +script_log_level="ERROR" + +log_message() { + local log_message=$1 + local log_message_priority=$2 + + # check if we provide and invalid log level + if [ -z "${levels[$log_message_priority]}" ]; then + return 1 + fi + + #check if the log level is above the script log level + if [ ${levels[$log_message_priority]} -lt ${levels[$script_log_level]} ]; then + return 2 + fi + + echo "${log_message_priority}: ${log_message}" +} + +if [ -z "${POD_NAME}" ]; then + log_message "No ${CLIENT_IMAGE_NAME} pod found" "ERROR" + exit 1 +fi + +if [ "$#" -ne 0 ]; then + param="$1" + if [ "${param}" == "-d" ]; then + MOUNT_PATH="$2" + log_message "Destination override = ${MOUNT_PATH}" "DEBUG" + shift + shift + fi +fi + +if [ "$#" -eq 0 ]; then + log_message "Invalid number of parameters" "ERROR" + log_message "Usage: $0 [-d destination] " "ERROR" + exit 1 +fi + +for file_name in "$@"; do + if [[ ! -d "$file_name" && ! -f "$file_name" ]]; then + log_message "Given file \"${file_name}\" not a file or directory" "ERROR" + exit 1 + fi +done + +for file_name in "$@"; do + log_message "Copying file \"${file_name}\" to pod \"${POD_NAME}\"" "DEBUG" + kubectl cp "${file_name}" "${NAMESPACE}/${POD_NAME}:${MOUNT_PATH}/" +done + diff --git a/utilities/platform-util/scripts/openstack-pod-exec.sh b/utilities/platform-util/scripts/openstack-pod-exec.sh new file mode 100755 index 000000000..956fdae8d --- /dev/null +++ b/utilities/platform-util/scripts/openstack-pod-exec.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CLIENT_IMAGE_NAME="openstack-clients" +NAMESPACE="openstack" +STATE="Running" +POD_NAME=$(kubectl -n ${NAMESPACE} get pods -o wide 2>&1 |grep ${CLIENT_IMAGE_NAME} |grep ${STATE} |awk '{print $1}') + +declare -A levels=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3) +script_log_level="ERROR" + +log_message() { + local log_message=$1 + local log_message_priority=$2 + + # check if we provide and invalid log level + if [ -z "${levels[$log_message_priority]}" ]; then + return 1 + fi + + #check if the log level is above the script log level + if [ ${levels[$log_message_priority]} -lt ${levels[$script_log_level]} ]; then + return 2 + fi + + echo "${log_message_priority}: ${log_message}" +} + +if [ -z "${POD_NAME}" ]; then + log_message "No openstackclients pod found" "ERROR" + exit 1 +fi + +log_message "Found clients pod: ${POD_NAME}" "DEBUG" + +# Pass stdin to the command only if we use a command that +# is expected to be interactive (like opening an openstack +# shell) +# This script should only be accessed through the defined +# aliases, so the first parameter is always passed. +# Depending on the existence of the second parameter, we +# decide if the command in interactive or not: +# Examples: +# - openstack (translates to ./openstack-pod-exec.sh openstack) +# only has one parameter and is expected to a open an +# interactive openstack shell +# - openstack endpoint list (translates to ./openstack-pod-exec.sh +# openstack endpoint list) is expected to run just one command +# and return the output +# If we had considered all commands as interactive, copying and +# pasting an openstack command followed by any other command +# would have passed all the input after the openstack call as +# input to the pod through "kubectl exec" and not execute the +# commands on the platform side. +if [ -z "$2" ]; then + exec kubectl exec -ti -n ${NAMESPACE} ${POD_NAME} -- "$@" +else + exec kubectl exec -t -n ${NAMESPACE} ${POD_NAME} -- "$@" +fi diff --git a/utilities/platform-util/scripts/osc-profile.sh b/utilities/platform-util/scripts/osc-profile.sh new file mode 100644 index 000000000..ea7d3fbf5 --- /dev/null +++ b/utilities/platform-util/scripts/osc-profile.sh @@ -0,0 +1,11 @@ +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then + alias openstack >/dev/null 2>&1 || alias openstack='/usr/local/bin/openstack-pod-exec.sh openstack' + alias nova >/dev/null 2>&1 || alias nova='/usr/local/bin/openstack-pod-exec.sh nova' + alias platform-openstack >/dev/null 2>&1 || alias platform-openstack=/usr/bin/openstack +fi