blob: 7d5a591f99fc9ac9e2572206b12e862875e3a31a [file] [log] [blame]
#!/bin/bash
# -----------------------------------------------------------------------------
# Copyright © 2018 AT&T USA
#
# 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.
#
# -----------------------------------------------------------------------------
#
# This script generates docker-compose volume overlay files from the oom
# kubernetes configuration files. Multiple environments can be supported. By
# default the environment is the 'local' environment and the docker-compose
# file is named docker-compose-local.yml. This script only generates the
# overlay files, not the docker-compose file.
#
# Overlay files contain the springboot configuration for each SO container.
#
# The idea here is that docker-compose is lighter weight than kubernetes with
# rancher, and people will find it easier to use in a development environment.
# Whenever the overlay files in oom are modified, this script can be used to
# (re)build overlay files for the docker-compose environment.
#
# Reasonably up-to-date overlay files for the docker-compose environment may
# be checked into the docker-config repository as a convenience to those who
# don't want to (or can't) run this script. This script will refresh those.
#
# Example Workflow:
#
# 1) build SO software and docker images -or- pull SO docker images from nexus3
#
# 2) Create configuration for 'local' environment:
# ./create-configs.sh -e local -i -u rd472p -b master
#
# 3) Start the environment:
# docker-compose -f docker-compose-local.yml up
#
function usage
{
echo "usage: $(basename $0) [-e env] [-i] [-u oom-git-user] [-b oom-git-branch]"
echo "where -e specifies the environment name (default: 'local')"
echo " -i re-initializes the staging directory (default: no)"
echo " -u specifies the git user for cloning oom (default: current user)"
echo " -b specifies the oom branch (default: current docker-config branch)"
}
#
# Purpose: prompts for a yes/no (or equivalent) answer
# Output: none
# Return Code: 0 for yes, 1 for no
# Usage: askConfirm prompt
#
function askConfirm
{
ask_prompt="$1"
while :
do
echo -n "$ask_prompt" >> /dev/tty
read ask_reply
ask_reply=${ask_reply##+([[:space:]])};
ask_reply=${ask_reply%%+([[:space:]])}
case "$ask_reply" in
y | yes | Y | YES)
return 0
;;
n | no | N | NO)
return 1
;;
esac
done
}
#
# Purpose: performs a literal string replacement (no regexs)
# Output: none, but modifies the specified file
# Return Code: 0 for success, 1 for failure
# Usage: replace source replacement file
#
function replace
{
local src=$1
local rpl=$2
local file=$3
if ! type xxd > /dev/null 2>&1
then
echo "xxd: command not found" 1>&2
return 1
fi
local xsrc=$(echo -n "$src" | xxd -p | tr -d '\n')
local xrpl=$(echo -n "$rpl" | xxd -p | tr -d '\n')
xxd -p $file | tr -d '\n' | sed "s/$xsrc/$xrpl/g" | xxd -p -r > $file.replace || return 1
mv $file.replace $file || return 1
return 0
}
#
# Purpose: converts a camel-case variable name to snake (upper) case
# openStackUserName -> OPEN_STACK_USER_NAME
# Output: the converted variable name
# Usage: toSnake name
#
function toSnake
{
echo "$1" | sed -r 's/([A-Z])/_\L\1/g' | sed 's/^_//' | tr '[a-z]' '[A-Z]'
}
#
# Purpose: lists all the environment variables in the specified docker
# compose yaml for the specified container, e.g.:
# VAR1=VALUE1
# VAR2=VALUE2
# ...
# Output: the list of variable mappings
# Usage: listEnv composeFile containerName
#
function listEnv
{
local composeFile=$1
local container=$2
local inContainer=FALSE
local inEnvironment=FALSE
while read line
do
if [[ $line == "$container:" ]]
then
inContainer=TRUE
elif [[ $inContainer == TRUE && $line == "environment:" ]]
then
inEnvironment=TRUE
else
if [[ $inEnvironment == TRUE ]]
then
if [[ ${line:0:1} == "-" ]]
then
echo "$line"
else
break
fi
fi
fi
done < $composeFile | sed -e "s/^- '//" -e "s/'$//"
}
#
# Purpose: tests if the specified environment variable is defined in the
# docker compose yaml for the specified container.
# Output: none
# Return Code: 0 if the variable exists, 1 if it doesn't
# Usage: varExists composeFile containerName variableName
#
function varExists
{
local composeFile=$1
local container=$2
local var=$3
listEnv $composeFile $container | grep "^$var=" > /dev/null
return $?
}
#
# Purpose: returns the value of the specified environment variable
# from the compose yaml for the specified container.
# Output: the variable value (empty if it isn't defined)
# Usage: varValue composeFile containerName variableName
#
function varValue
{
local composeFile=$1
local container=$2
local var=$3
listEnv $composeFile $container | grep "^$var=" | cut -d= -f2
}
### MAIN CODE STARTS HERE
if [[ ! -d volumes/so ]]
then
echo "You must run this command in the docker-config directory" 1>&2
exit 1
fi
ENV=local
INIT=FALSE
GITUSER=$(id -un)
GITBRANCH=$(git rev-parse --abbrev-ref HEAD)
while getopts :e:iu:b: c
do
case "$c" in
e)
ENV=$OPTARG
;;
i)
INIT=TRUE
;;
u)
GITUSER=$OPTARG
;;
b)
GITBRANCH=$OPTARG
;;
*)
usage 1>&2
exit 1
;;
esac
done
shift $(($OPTIND - 1))
if [[ $# != 0 ]]
then
usage 1>&2
exit 1
fi
if [[ ! -f docker-compose-$ENV.yml ]]
then
echo "No such file: docker-compose-$ENV.yml" 1>&2
exit 1
fi
mkdir -p staging
if [[ -d staging && $INIT == TRUE ]]
then
if ! askConfirm "Delete existing staging directory? "
then
exit 1
fi
rm -fr staging || exit 1
fi
mkdir -p staging || exit 1
# Get the oom repository from gerrit.
if [[ -d staging/oom ]]
then
cd staging/oom || exit 1
branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch != $GITBRANCH ]]
then
echo "staging/oom is not on branch '$GITBRANCH'" 1>&2
exit 1
fi
cd ../.. || exit 1
else
cd staging || exit 1
echo "Cloning into staging/oom"
git clone https://$GITUSER@gerrit.onap.org/r/a/oom || exit 1
cd oom || exit 1
branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch != $GITBRANCH ]]
then
if [[ $(git ls-remote origin $GITBRANCH | wc -l) == 0 ]]
then
echo "staging/oom has no '$GITBRANCH' branch" 1>&2
exit 1
fi
echo "Switching staging/oom to '$GITBRANCH' branch"
git checkout -b $GITBRANCH remotes/origin/$GITBRANCH || exit 1
fi
cd ../.. || exit 1
fi
kso=staging/oom/kubernetes/so
if [[ ! -d $kso ]]
then
echo "No such directory: $kso" 1>&2
exit 1
fi
if [[ ! -d staging/volumes/so/config ]]
then
mkdir -p staging/volumes/so/config
fi
stagedTargets=
for override in $(cd $kso && find * -name 'override.yaml')
do
subdir=${override%%/*}
if [[ $subdir == resources ]]
then
container=so-api-handler-infra
elif [[ $subdir == charts ]]
then
container=${override#charts/}
container=${container%%/*}
fi
if [[ $container != so-monitoring ]]
then
container=${container#so-}
fi
target=staging/volumes/so/config/$container/$ENV/override.yaml
if [[ ! -f $target ]]
then
mkdir -p $(dirname $target) || exit 1
cp $kso/$override $target.tmp || exit 1
if ! varExists docker-compose-$ENV.yml $container COMMON_NAMESPACE
then
echo "ERROR: no COMMON_NAMESPACE variable is defined in docker-compose-$ENV.yml for container $container" 1>&2
exit 1
fi
replace '{{ include "common.namespace" . }}' '${COMMON_NAMESPACE}' $target.tmp || exit 1
if ! varExists docker-compose-$ENV.yml $container CONTAINER_PORT
then
echo "ERROR: no CONTAINER_PORT variable is defined in docker-compose-$ENV.yml for container $container" 1>&2
exit 1
fi
replace '{{ index .Values.containerPort }}' '${CONTAINER_PORT}' $target.tmp || exit 1
for configValue in $(grep "{{ \.Values\.config\..*}}" $target.tmp | cut -d'{' -f3 | cut -d'}' -f1 | tr -d ' ' | sed 's/.Values.config.//' | sort -u)
do
var=$(toSnake $configValue)
if ! varExists docker-compose-$ENV.yml $container $var
then
echo "ERROR: no $var variable is defined in docker-compose-$ENV.yml for container $container" 1>&2
exit 1
fi
if [[ ${var:0:11} == "OPEN_STACK_" ]]
then
# Workaround for variables in the openstack
# adapter cloud configuration. The override
# yaml is read by a migration program that
# doesn't expand variables, so we need to
# substitute the variable values here.
value=$(varValue docker-compose-$ENV.yml $container $var)
replace "{{ .Values.config.$configValue }}" "$value" $target.tmp || exit 1
else
replace "{{ .Values.config.$configValue }}" '${'$var'}' $target.tmp || exit 1
fi
done
if grep "{{" $target.tmp > /dev/null
then
echo "ERROR: Unresolved placeholders in $kso/$override:" 1>&2
grep "{{.*}}" $target.tmp | cut -d'{' -f3 | cut -d'}' -f1 | sed -e 's/^/ {{/' -e 's/$/}}/' | sort -u 1>&2
exit 1
fi
mv $target.tmp $target || exit 1
echo "Created $target"
stagedTargets="$stagedTargets target"
fi
done
for override in $(cd staging && find volumes -name 'override.yaml')
do
dir=$(dirname $override)
mkdir -p $dir || exit 1
cp staging/$override $override || exit 1
echo "Installed $override"
done
echo "SUCCESS"