mirror of
https://github.com/OpenMTC/OpenMTC.git
synced 2024-12-18 20:47:58 +00:00
444 lines
12 KiB
Bash
Executable File
444 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
base_path=$(cd $(dirname "${0}"); pwd)
|
|
|
|
prog_name="create-binary-docker"
|
|
prog_version="0.1"
|
|
version_str="${prog_name} v${prog_version}"
|
|
usage_str="${prog_name} [OPTS] <module_name>
|
|
OPTS:
|
|
-a|--arch <ARCH> Choose architecture: amd64|arm
|
|
-p|--prefix <Name Prefix> Choose Docker image name prefix
|
|
-e|--export Export the Docker image to a file, after build
|
|
|
|
-h|--help Show this help
|
|
-v|--version Show version information
|
|
|
|
module_name:
|
|
gateway | backend
|
|
"
|
|
|
|
version () {
|
|
echo "${version_str}"
|
|
}
|
|
|
|
usage () {
|
|
echo "Usage: $usage_str"
|
|
}
|
|
|
|
separator_line () {
|
|
counter=${1-80}
|
|
printf '%'${counter}'s\n' | tr ' ' '#'
|
|
}
|
|
|
|
#
|
|
# Parsing commandline options and arguments using "getopt"
|
|
#
|
|
OPTS=$(getopt -o 'a:ehp:v' --long 'arch:,export,help,prefix:,version' -n "${prog_name}" -- "$@")
|
|
if [ 0 -ne $? ]; then
|
|
echo 'Exiting' >&2
|
|
exit 1
|
|
fi
|
|
eval set -- "$OPTS"
|
|
unset OPTS
|
|
|
|
ARCH_OPT=''
|
|
PREFIX_OPT=''
|
|
EXPORT_OPT=''
|
|
MODULE_NAME=''
|
|
|
|
while true; do
|
|
case "$1" in
|
|
'-a' | '--arch')
|
|
ARCH_OPT="$2"
|
|
shift 2
|
|
continue
|
|
;;
|
|
|
|
'-e' | '--export')
|
|
EXPORT_OPT=true
|
|
shift 1
|
|
continue
|
|
;;
|
|
|
|
'-h' | '--help')
|
|
usage
|
|
exit 0
|
|
;;
|
|
|
|
'-p' | '--prefix')
|
|
PREFIX_OPT="$2"
|
|
shift 2
|
|
continue
|
|
;;
|
|
|
|
'-v' | '--version')
|
|
version
|
|
shift 1
|
|
exit 0
|
|
;;
|
|
|
|
'--') # Argument handling
|
|
shift # Remove '--'
|
|
if [ $# -ne 1 ]; then
|
|
echo "Error: Exactly one module name needs to be provided" >&2
|
|
usage
|
|
exit 1
|
|
fi
|
|
MODULE_NAME="$1"
|
|
break
|
|
;;
|
|
*)
|
|
echo "Error: Internal problem!"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Set architecture
|
|
case ${ARCH_OPT} in
|
|
amd64)
|
|
machine="amd64"
|
|
arch="x86_64"
|
|
;;
|
|
|
|
arm)
|
|
machine="arm"
|
|
arch="armv7l"
|
|
if [ $(uname -m) == "x86_64" ];then
|
|
printf "check qemu"
|
|
qemu_bin=$(which qemu-arm-static)
|
|
if [ -z "$qemu_bin" ];then
|
|
printf "Package 'qemu-user-static' not found"
|
|
printf "Script is exiting now.\n"
|
|
exit 1
|
|
fi
|
|
fi
|
|
;;
|
|
|
|
'')
|
|
case $(uname -m) in
|
|
x86_64)
|
|
machine="amd64"
|
|
arch="x86_64"
|
|
;;
|
|
armv6l|armv7l)
|
|
machine="arm"
|
|
arch="armv7l"
|
|
;;
|
|
*)
|
|
printf "Platform %s is not supported!\n" $(uname -m)
|
|
printf "Script is exiting now.\n"
|
|
exit 1
|
|
;;
|
|
esac
|
|
;;
|
|
|
|
*)
|
|
echo "Error: Unknown architecture ${ARCH_OPT}" >&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
|
|
esac
|
|
|
|
# get docker image to build
|
|
case ${MODULE_NAME} in
|
|
backend|be)
|
|
name="backend"
|
|
setup_file="setup-gevent-all.py"
|
|
binary_prefix="openmtc-all"
|
|
;;
|
|
gateway|gw)
|
|
name="gateway"
|
|
setup_file="setup-gevent-all.py"
|
|
binary_prefix="openmtc-all"
|
|
;;
|
|
help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*) # other images will be detected by scanning setup files
|
|
name="$1"
|
|
setup_file="setup-${name}.py"
|
|
binary_prefix="openmtc-${name}"
|
|
;;
|
|
esac
|
|
|
|
# Use export image, if set
|
|
export_image=${EXPORT_OPT:-false}
|
|
|
|
#
|
|
# docker variables
|
|
#
|
|
docker_prefix_default="openmtc/"
|
|
if [ -n "${PREFIX_OPT}" ]; then
|
|
docker_prefix="${PREFIX_OPT%%/}/"
|
|
else
|
|
docker_prefix=${docker_prefix_default}
|
|
fi
|
|
|
|
# get setup file and set working dir
|
|
find_result=($(find ${base_path} -iname "${setup_file}"))
|
|
|
|
if [ ${#find_result[*]} -eq 0 ]; then
|
|
echo "Setup file ${setup_file} not existing. Exiting Now!."
|
|
exit 1
|
|
fi
|
|
|
|
if [ ${#find_result[*]} -gt 1 ]; then
|
|
echo "Too many setup files matching the name. Exiting Now!."
|
|
exit 1
|
|
fi
|
|
|
|
working_dir=$(dirname ${find_result[0]})
|
|
|
|
# docker variables
|
|
docker_path="${working_dir}/docker"
|
|
docker_tmp="${docker_path}/tmp"
|
|
|
|
# base image
|
|
base_docker_file="${docker_path}/base-${machine}"
|
|
base_docker_name="${docker_prefix}base-${machine}"
|
|
|
|
# builder image
|
|
build_docker_file="${docker_path}/builder-${machine}"
|
|
build_docker_name="${docker_prefix}builder-${machine}"
|
|
build_docker_work_dir="/usr/local/src/openmtc-python/"
|
|
build_container_name="build-container"
|
|
|
|
# docker image
|
|
target_docker_name="${docker_prefix}${name}-${machine}"
|
|
target_docker_file="${docker_path}/${name}-${machine}"
|
|
target_docker_binary="${docker_tmp}/openmtc-${name}.tar.gz"
|
|
|
|
# export image
|
|
docker_dist="${base_path}/dist/docker"
|
|
|
|
# check if python is installed
|
|
if ! $(which python) --version >/dev/null 2>&1; then
|
|
echo "Python is not installed. Exiting now."
|
|
exit 2
|
|
fi
|
|
|
|
# check if default python version is 2.x
|
|
python_version_getter="import sys; print('%s%s' % (sys.version_info.major, sys.version_info.minor))"
|
|
if [ $($(which python) -c "${python_version_getter}") != "27" ]; then
|
|
echo "Default python version should be 2.7. Exiting now."
|
|
exit 2
|
|
fi
|
|
|
|
# check if python-setuptools is available
|
|
if ! $(which python) -c "import setuptools" >/dev/null 2>&1; then
|
|
echo -n "Setuptools for python is not installed. "
|
|
echo "Please use pip or OS package manager to install it. Exiting now."
|
|
exit 2
|
|
fi
|
|
|
|
# check if docker is installed
|
|
if ! $(which docker) --version >/dev/null 2>&1; then
|
|
echo "docker is not installed. Exiting now."
|
|
exit 2
|
|
fi
|
|
|
|
##############################################################################
|
|
# set docker command
|
|
# only sudo if not root and not in docker group
|
|
if [ $(id -u) -eq 0 ] || id -nG | grep -qw "docker"; then
|
|
docker_cmd=$(which docker)
|
|
else
|
|
docker_cmd="sudo "$(which docker)
|
|
fi
|
|
|
|
##############################################################################
|
|
# trap and cleanup
|
|
cleanup () {
|
|
separator_line
|
|
printf "### Cleaning..."
|
|
rm -f "${target_docker_binary}"
|
|
rm -f "${docker_tmp}/${name}-dependencies.txt"
|
|
${docker_cmd} rm -f ${build_container_name} &> /dev/null
|
|
printf "done\n"
|
|
|
|
# remove dangling images
|
|
separator_line
|
|
printf "### Removing dangled images..."
|
|
for image in $(${docker_cmd} images -qa -f "dangling=true"); do
|
|
${docker_cmd} rmi -f ${image} > /dev/null
|
|
done
|
|
printf "done\n"
|
|
}
|
|
|
|
trap cleanup SIGINT SIGTERM
|
|
|
|
##############################################################################
|
|
# check if possible
|
|
target_setup_file="${working_dir}/${setup_file}"
|
|
if ! ([ -f "${target_setup_file}" ] && [ -f "${target_docker_file}" ]); then
|
|
if ! [ -f "${target_setup_file}" ]; then
|
|
printf "${target_setup_file} not existing\n"
|
|
fi
|
|
if ! [ -f "${target_docker_file}" ]; then
|
|
printf "${target_docker_file} not existing\n"
|
|
fi
|
|
printf "Script is exiting now.\n"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
|
|
##############################################################################
|
|
# Use this script to build sdk package before if necessary
|
|
if [ "${name}" != "sdk" ]; then
|
|
separator_line
|
|
printf "### Need to build SDK before.\n"
|
|
|
|
# Run this script again to build sdk
|
|
$0 -a ${machine} -p ${docker_prefix} sdk
|
|
if [ $? -gt 0 ]; then
|
|
exit 1
|
|
fi
|
|
separator_line
|
|
printf "### Continuing %s-%s...\n" ${name} ${machine}
|
|
fi
|
|
|
|
##############################################################################
|
|
separator_line
|
|
printf "### Building docker image for %s-%s...\n" ${name} ${machine}
|
|
|
|
##############################################################################
|
|
# When building SDK, build base and build container before
|
|
if [ "${name}" == "sdk" ]; then
|
|
##########################################################################
|
|
# build base docker container
|
|
separator_line
|
|
printf "### Building base container...\n"
|
|
${docker_cmd} build --tag ${base_docker_name} \
|
|
--file ${base_docker_file} ${docker_path}
|
|
if [ $? -gt 0 ]; then
|
|
printf "### Building base container failed. Exiting now.\n"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
printf "### Base container built successfully.\n"
|
|
|
|
##########################################################################
|
|
# build container to run setup script
|
|
separator_line
|
|
printf "### Building build container...\n"
|
|
${docker_cmd} build --tag ${build_docker_name} \
|
|
--build-arg OPENMTC_HOME=${build_docker_work_dir} \
|
|
--file ${build_docker_file} ${docker_path}
|
|
if [ $? -gt 0 ]; then
|
|
printf "### Building build container failed. Exiting now.\n"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
printf "### Build container built successfully.\n"
|
|
fi
|
|
|
|
##############################################################################
|
|
# create the build container to run the script
|
|
separator_line
|
|
printf "### Create build container %s.\n" ${name}
|
|
${docker_cmd} create --name ${build_container_name} \
|
|
--volume=${base_path}:${build_docker_work_dir} \
|
|
${build_docker_name} ${name} "$(id -u):$(id -g)"
|
|
if [ $? -gt 0 ]; then
|
|
printf "### Creating build container failed. Exiting now.\n"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
printf "### Creating build container successfully.\n"
|
|
|
|
##############################################################################
|
|
# starting container interactive to wait for finishing the script
|
|
separator_line
|
|
printf "### Starting build container...\n"
|
|
${docker_cmd} start -i ${build_container_name}
|
|
if [ $? -gt 0 ]; then
|
|
printf "### Starting build container failed. Exiting now.\n"
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
printf "### Starting build container successful.\n"
|
|
|
|
##############################################################################
|
|
# move the file
|
|
separator_line
|
|
printf "### Move tar file...\n"
|
|
mkdir -p ${docker_tmp}
|
|
binary_archive="${binary_prefix}.docker.tar.gz"
|
|
binary_archive="${working_dir}/dist/${binary_archive}"
|
|
mv ${binary_archive} ${target_docker_binary}
|
|
printf "### Moving tar successful.\n"
|
|
|
|
##############################################################################
|
|
# copy requirements
|
|
get_requirements_from_setup_file ()
|
|
{
|
|
# Each setup file is assumed to hold ".py" suffix, this gets
|
|
# removed here
|
|
local module_name=${setup_file%.py}
|
|
|
|
cd ${working_dir}
|
|
python - << END_OF_PYTHON
|
|
from importlib import import_module
|
|
from re import sub
|
|
setup = import_module('${module_name}', '${module_name}')
|
|
print('\n'.join(map(lambda x: sub('[\s+]', '', x),
|
|
setup.SETUP_INSTALL_REQUIRES)))
|
|
END_OF_PYTHON
|
|
}
|
|
|
|
printf "%s\n" $(get_requirements_from_setup_file) | tr " " "\n" > \
|
|
"${docker_tmp}/${name}-dependencies.txt"
|
|
|
|
##############################################################################
|
|
# build docker container
|
|
separator_line
|
|
printf "### Building %s-%s container...\n" ${name} ${machine}
|
|
|
|
${docker_cmd} build --force-rm -t ${target_docker_name} \
|
|
-f ${target_docker_file} ${docker_path}
|
|
if [ $? -gt 0 ]; then
|
|
printf "### Building %s-%s container failed. Exiting now.\n" \
|
|
${name} ${machine}
|
|
cleanup
|
|
exit 1
|
|
fi
|
|
printf "### Base %s-%s container built successfully.\n" ${name} ${machine}
|
|
|
|
##############################################################################
|
|
# cleanup
|
|
cleanup
|
|
|
|
##############################################################################
|
|
# example to run the docker file
|
|
#${docker_cmd} run --name test -d \
|
|
# -p 0.0.0.0:8001:8001 \
|
|
# -e "EXTERNAL_IP=$(ip r get 8.8.8.8 | awk 'NR==1 {print $NF}')" \
|
|
# ${target_docker_name}
|
|
|
|
# test with curl
|
|
#curl $(ip r get 8.8.8.8 | awk 'NR==1 {print $NF}'):5001/m2m
|
|
|
|
# stop and remove container again
|
|
#${docker_cmd} stop test && ${docker_cmd} rm test
|
|
|
|
##############################################################################
|
|
# export docker image
|
|
if ${export_image}; then
|
|
separator_line
|
|
printf "### Exporting the image..."
|
|
mkdir -p ${docker_dist}
|
|
# change / in target_docker_name to -
|
|
docker_dist_file="${docker_dist}/${target_docker_name//\//-}.tar.gz"
|
|
${docker_cmd} save ${target_docker_name} | gzip -c > ${docker_dist_file}
|
|
printf "done\n"
|
|
fi
|
|
|
|
# import docker image
|
|
#zcat ${target_docker_name}.tar.gz | ${docker_cmd} load
|
|
|