mirror of
https://github.com/OpenMTC/OpenMTC.git
synced 2024-12-22 14:22:30 +00:00
544 lines
14 KiB
Bash
Executable File
544 lines
14 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# OS relevant options
|
|
case "${OSTYPE}" in
|
|
"linux-gnu")
|
|
MD5_PROG="md5sum"
|
|
;;
|
|
"darwin")
|
|
MD5_PROG="md5 -r"
|
|
;;
|
|
*)
|
|
echo "OS type '${OSTYPE}' not supported. Exiting now!"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
print_help () {
|
|
cat <<EOM
|
|
|
|
Usage: $0 [-w] [-d] [-i] [-a <APP_SCRIPT>] APP_NAME
|
|
|
|
APP_NAME Name of the app, used as folder and class name.
|
|
|
|
-a <APP_SCRIPT> If not provided, it will be created automatically by
|
|
converting the APP_NAME from camel case to snake case.
|
|
|
|
If APP_NAME or APP_SCRIPT ends with IPE or similar, it
|
|
will be assumed as IPE and will be created under ipes.
|
|
|
|
-w if true, FlaskRunner is used and basic index.html is
|
|
created
|
|
|
|
-i if true, IN-AE is expected and default endpoint is
|
|
configured to backend
|
|
|
|
-d if true, no setup file and docker files will be created
|
|
EOM
|
|
}
|
|
|
|
optspec=":wdia:"
|
|
|
|
WEB_APP="false"
|
|
IN_AE="false"
|
|
NO_DOCKER="false"
|
|
|
|
while getopts "${optspec}" optchar; do
|
|
case "${optchar}" in
|
|
w)
|
|
WEB_APP="true"
|
|
;;
|
|
i)
|
|
IN_AE="true"
|
|
;;
|
|
d)
|
|
NO_DOCKER="true"
|
|
;;
|
|
a)
|
|
if [[ ${OPTARG} == -* ]]; then
|
|
print_help
|
|
exit 1
|
|
fi
|
|
APP_SCRIPT=${OPTARG}
|
|
;;
|
|
\?|:)
|
|
print_help
|
|
exit 1
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND-1))
|
|
|
|
if [ $# -ne 1 ]; then
|
|
print_help
|
|
exit 1
|
|
fi
|
|
|
|
# set variables
|
|
APP_NAME="$1"
|
|
APP_SCRIPT=${APP_SCRIPT-$(printf "${APP_NAME}" | \
|
|
perl -p -e 's/([a-z0-9])([A-Z]+)/\1-\L\2/g' | \
|
|
perl -p -e 's/^([A-Z])/\l$1/g')}
|
|
MOD_NAME=$(printf "${APP_SCRIPT}" | tr "-" "_" | sed 's/.*/\L&/g')
|
|
PKG_NAME=$(printf "${APP_SCRIPT}" | tr -d "-" | sed 's/.*/\L&/g')
|
|
|
|
if [[ ${PKG_NAME} == *"ipe" ]]; then
|
|
APPS_FOLDER="ipes"
|
|
else
|
|
APPS_FOLDER="apps"
|
|
fi
|
|
APP_FOLDER="${APPS_FOLDER}/${APP_NAME}"
|
|
|
|
# check if existing
|
|
if [ -e "${APP_FOLDER}" ]; then
|
|
printf "App folder already existing. Aborting.\n"
|
|
exit 1
|
|
fi
|
|
|
|
# check if APP_NAME and APP_SCRIPT are the same. Testing lowercase for case-insensitive filesystems
|
|
if [ "${APP_NAME,,}" == "${APP_SCRIPT,,}" ]; then
|
|
echo "APP_NAME and APP_SCRIPT shouldn't be the same, specially in case-insensitive systems. Aborting\n"
|
|
exit 1
|
|
fi
|
|
|
|
# change to root folder
|
|
cd "$(dirname ${0})"
|
|
|
|
# set port suffix
|
|
APP_PORT_SUFFIX=$(printf %04d $((0x$(${MD5_PROG} <<< "${APP_NAME}" | cut -c1-4) % 10000)))
|
|
|
|
################################################################################
|
|
# creating module files
|
|
mkdir -p "${APP_FOLDER}"
|
|
|
|
SRC_FOLDER="${APP_FOLDER}/src/${PKG_NAME}"
|
|
mkdir -p "${SRC_FOLDER}"
|
|
|
|
# init file
|
|
cat > "${SRC_FOLDER}/__init__.py" << EOF
|
|
"""
|
|
TODO: Add description here
|
|
"""
|
|
|
|
__version__ = "ADD-VERSION-HERE"
|
|
__description__ = "${APP_NAME}"
|
|
__author_name__ = "ADD_AUTHOR_HERE"
|
|
__author_mail__ = "ADD_MAIL_HERE"
|
|
__requires__ = []
|
|
EOF
|
|
|
|
# main file
|
|
MAIN_MODULE="${SRC_FOLDER}/__main__.py"
|
|
cat > "${MAIN_MODULE}" << EOF
|
|
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
|
|
|
|
from openmtc_app.util import prepare_app, get_value
|
|
from openmtc_app.flask_runner import FlaskRunner as Runner
|
|
from .${MOD_NAME} import ${APP_NAME}
|
|
|
|
# defaults
|
|
default_name = "${APP_NAME}"
|
|
default_ep = "http://localhost:8000"
|
|
|
|
# args parser
|
|
parser = ArgumentParser(
|
|
description="An IPE called ${APP_NAME}",
|
|
prog="${APP_NAME}",
|
|
formatter_class=ArgumentDefaultsHelpFormatter)
|
|
parser.add_argument("-n", "--name", help="Name used for the AE.")
|
|
parser.add_argument("-s", "--ep", help="URL of the local Endpoint.")
|
|
|
|
# args, config and logging
|
|
args, config = prepare_app(parser, __loader__, __name__, "config.json")
|
|
|
|
# variables
|
|
nm = get_value("name", (unicode, str), default_name, args, config)
|
|
cb = config.get("cse_base", "onem2m")
|
|
ep = get_value("ep", (unicode, str), default_ep, args, config)
|
|
poas = config.get("poas", ["http://auto:2${APP_PORT_SUFFIX}"])
|
|
originator_pre = config.get("originator_pre", "//openmtc.org/mn-cse-1")
|
|
ssl_certs = config.get("ssl_certs", {})
|
|
port = int(config.get("port", 1${APP_PORT_SUFFIX}))
|
|
|
|
# start
|
|
app = ${APP_NAME}(
|
|
name=nm, cse_base=cb, poas=poas,
|
|
originator_pre=originator_pre, **ssl_certs
|
|
)
|
|
Runner(app, port=port).run(ep)
|
|
|
|
print ("Exiting....")
|
|
EOF
|
|
|
|
if [ ${WEB_APP} == "false" ]; then
|
|
perl -i -p -e 's/flask_runner/runner/' "${MAIN_MODULE}"
|
|
perl -i -p -e 's/FlaskRunner/AppRunner/' "${MAIN_MODULE}"
|
|
perl -i -p -e 's/app, port=port/app/' "${MAIN_MODULE}"
|
|
perl -i -n -e 'print unless /port = int\(/' "${MAIN_MODULE}"
|
|
fi
|
|
|
|
if [ ${IN_AE} == "true" ]; then
|
|
perl -i -p -e 's/mn-cse-1/in-cse-1/' "${MAIN_MODULE}"
|
|
perl -i -p -e 's/localhost:8000/localhost:18000/' "${MAIN_MODULE}"
|
|
fi
|
|
|
|
# main module
|
|
cat > "${SRC_FOLDER}/${MOD_NAME}.py" << EOF
|
|
from openmtc_app.onem2m import XAE
|
|
|
|
|
|
class ${APP_NAME}(XAE):
|
|
interval = 10
|
|
|
|
def _on_register(self):
|
|
# start endless loop
|
|
self.run_forever(self.interval)
|
|
EOF
|
|
|
|
# index html if web app
|
|
if [ ${WEB_APP} == "true" ]; then
|
|
mkdir -p "${SRC_FOLDER}/static"
|
|
cat > "${SRC_FOLDER}/static/index.html" << EOF
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Title</title>
|
|
</head>
|
|
<body>
|
|
Hello World!
|
|
</body>
|
|
</html>
|
|
EOF
|
|
fi
|
|
|
|
################################################################################
|
|
# creating config files
|
|
|
|
mkdir -p "${APP_FOLDER}/etc/conf"
|
|
|
|
# main config
|
|
MAIN_CONFIG="${APP_FOLDER}/config.json"
|
|
cat > "${MAIN_CONFIG}" << EOF
|
|
{
|
|
"name": "${APP_NAME}",
|
|
"ep": "http://localhost:8000",
|
|
"cse_base": "onem2m",
|
|
"poas": [
|
|
"http://auto:2${APP_PORT_SUFFIX}"
|
|
],
|
|
"originator_pre": "//openmtc.org/mn-cse-1",
|
|
"ssl_certs": {
|
|
"cert_file": null,
|
|
"key_file": null,
|
|
"ca_certs": null
|
|
},
|
|
"port": 1${APP_PORT_SUFFIX},
|
|
"logging": {
|
|
"level": "ERROR",
|
|
"file": null
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# dist config
|
|
DIST_CONFIG="${APP_FOLDER}/etc/conf/config.json.dist"
|
|
cat > "${DIST_CONFIG}" << EOF
|
|
{
|
|
"name": "${APP_NAME}",
|
|
"ep": "http://localhost:8000",
|
|
"cse_base": "onem2m",
|
|
"poas": [
|
|
"http://auto:2${APP_PORT_SUFFIX}"
|
|
],
|
|
"originator_pre": "//openmtc.org/mn-cse-1",
|
|
"ssl_certs": {
|
|
"cert_file": "/etc/openmtc/certs/${PKG_NAME}.cert.pem",
|
|
"key_file": "/etc/openmtc/certs/${PKG_NAME}.key.pem",
|
|
"ca_certs": "/etc/openmtc/certs/ca-chain.cert.pem"
|
|
},
|
|
"port": 1${APP_PORT_SUFFIX},
|
|
"logging": {
|
|
"level": "INFO",
|
|
"file": "/var/log/openmtc/${PKG_NAME}.log"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
if [ ${WEB_APP} == "false" ]; then
|
|
perl -i -n -e 'print unless /"port": 1/' "${MAIN_CONFIG}"
|
|
perl -i -n -e 'print unless /"port": 1/' "${DIST_CONFIG}"
|
|
fi
|
|
|
|
if [ ${IN_AE} == "true" ]; then
|
|
perl -i -p -e 's/mn-cse-1/in-cse-1/' "${MAIN_CONFIG}"
|
|
perl -i -p -e 's/localhost:8000/localhost:18000/' "${MAIN_CONFIG}"
|
|
perl -i -p -e 's/mn-cse-1/in-cse-1/' "${DIST_CONFIG}"
|
|
perl -i -p -e 's/localhost:8000/localhost:18000/' "${DIST_CONFIG}"
|
|
fi
|
|
|
|
################################################################################
|
|
# create start script
|
|
START_SCRIPT="${APPS_FOLDER}/${APP_SCRIPT}"
|
|
cat > "${START_SCRIPT}" << EOF
|
|
#!/usr/bin/env bash
|
|
|
|
cd \$(dirname \${0})
|
|
|
|
. ./prep-env.sh
|
|
|
|
cd ${APP_NAME}
|
|
|
|
PYTHONPATH=\${PYTHONPATH}:src exec python -m ${PKG_NAME} \$@
|
|
EOF
|
|
|
|
chmod +x "${START_SCRIPT}"
|
|
|
|
################################################################################
|
|
# create bin script
|
|
mkdir -p "${APP_FOLDER}/bin"
|
|
BIN_SCRIPT="${APP_FOLDER}/bin/openmtc-${APP_SCRIPT}"
|
|
cat > "${BIN_SCRIPT}" << EOF
|
|
#!/usr/bin/env bash
|
|
|
|
exec python -m ${PKG_NAME} \$@
|
|
EOF
|
|
|
|
chmod +x "${BIN_SCRIPT}"
|
|
|
|
################################################################################
|
|
# create systemd unit file
|
|
SYSTEMD_FOLDER="${APP_FOLDER}/etc/systemd/system"
|
|
mkdir -p ${SYSTEMD_FOLDER}
|
|
cat > "${SYSTEMD_FOLDER}/openmtc-${PKG_NAME}.service" << EOF
|
|
[Unit]
|
|
Description=OpenMTC ${APP_NAME}
|
|
After=network.target
|
|
Wants=ntp.service
|
|
|
|
[Service]
|
|
ExecStart=/usr/local/bin/${APP_SCRIPT}
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
################################################################################
|
|
# return here if docker is not needed
|
|
if [ ${NO_DOCKER} == "true" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
################################################################################
|
|
# create setup file
|
|
SETUP_FILE="${APP_FOLDER}/setup-${PKG_NAME}.py"
|
|
cat > "${SETUP_FILE}" << EOF
|
|
#!/usr/bin/env python
|
|
|
|
from setuptools import setup
|
|
from distutils.core import setup
|
|
from glob import glob
|
|
import sys
|
|
|
|
from utils import get_packages, get_pkg_files, OpenMTCSdist, move_config_files
|
|
|
|
# name and dir
|
|
NAME = "${PKG_NAME}"
|
|
BASE_DIR = "."
|
|
|
|
# import pkg
|
|
sys.path.append(BASE_DIR + "/src")
|
|
pkg = __import__(NAME)
|
|
|
|
# setup name and version
|
|
SETUP_NAME = "openmtc-" + NAME
|
|
SETUP_VERSION = pkg.__version__
|
|
SETUP_DESCRIPTION = pkg.__description__
|
|
|
|
# meta
|
|
SETUP_AUTHOR = pkg.__author_name__
|
|
SETUP_AUTHOR_EMAIL = pkg.__author_mail__
|
|
SETUP_URL = "http://www.openmtc.org"
|
|
SETUP_LICENSE = "Fraunhofer FOKUS proprietary"
|
|
|
|
# requirements
|
|
SETUP_REQUIRES = pkg.__requires__
|
|
SETUP_INSTALL_REQUIRES = pkg.__requires__
|
|
|
|
# packages
|
|
PACKAGES = [NAME]
|
|
PACKAGE_DIR = {"": BASE_DIR + "/src"}
|
|
all_packages = []
|
|
for package in PACKAGES:
|
|
all_packages.extend(get_packages(package, PACKAGE_DIR))
|
|
|
|
# scripts
|
|
SETUP_SCRIPTS = glob(BASE_DIR + "/bin/*")
|
|
|
|
# package data
|
|
PACKAGE_DATA = {NAME: get_pkg_files(BASE_DIR, NAME)}
|
|
|
|
# data files
|
|
CONFIG_FILES = ("config.json",)
|
|
CONFIG_DIR = "/etc/openmtc/" + NAME
|
|
CONFIG_DIST_FILES = (BASE_DIR + "/etc/conf/config.json.dist",)
|
|
DATA_FILES = [(CONFIG_DIR, CONFIG_DIST_FILES)]
|
|
|
|
# cmd class
|
|
CMD_CLASS = {'sdist': OpenMTCSdist}
|
|
|
|
if __name__ == "__main__":
|
|
if 'bdist_wheel' in sys.argv:
|
|
raise RuntimeError("This setup.py does not support wheels")
|
|
|
|
############################################################################
|
|
# setup
|
|
setup(name=SETUP_NAME,
|
|
version=SETUP_VERSION,
|
|
description=SETUP_DESCRIPTION,
|
|
author=SETUP_AUTHOR,
|
|
author_email=SETUP_AUTHOR_EMAIL,
|
|
url=SETUP_URL,
|
|
license=SETUP_LICENSE,
|
|
requires=SETUP_REQUIRES,
|
|
install_requires=SETUP_INSTALL_REQUIRES,
|
|
package_dir=PACKAGE_DIR,
|
|
packages=all_packages,
|
|
scripts=SETUP_SCRIPTS,
|
|
package_data=PACKAGE_DATA,
|
|
data_files=DATA_FILES,
|
|
cmdclass=CMD_CLASS
|
|
)
|
|
|
|
############################################################################
|
|
# install
|
|
if "install" in sys.argv:
|
|
# only do this during install
|
|
move_config_files(CONFIG_DIR, CONFIG_FILES)
|
|
EOF
|
|
|
|
chmod +x "${SETUP_FILE}"
|
|
|
|
# copy needed helper files
|
|
cp MANIFEST.in utils.py "${APP_FOLDER}/."
|
|
|
|
################################################################################
|
|
# create docker files
|
|
|
|
DOCKER_FOLDER="${APP_FOLDER}/docker"
|
|
mkdir -p ${DOCKER_FOLDER}
|
|
|
|
# create configure script
|
|
DOCKER_SCRIPT="${DOCKER_FOLDER}/configure-${PKG_NAME}-and-start"
|
|
cat > "${DOCKER_SCRIPT}" << EOF
|
|
#!/usr/bin/env bash
|
|
|
|
CONFIG_FILE="/etc/openmtc/${PKG_NAME}/config.json"
|
|
|
|
NAME=\${NAME-"${APP_NAME}"}
|
|
EP=\${EP-"http://localhost:8000"}
|
|
CSE_BASE=\${CSE_BASE-"onem2m"}
|
|
POAS=\${POAS-'["http://auto:2${APP_PORT_SUFFIX}"]'}
|
|
ORIGINATOR_PRE=\${ORIGINATOR_PRE-"//openmtc.org/mn-cse-1"}
|
|
SSL_CRT=\${SSL_CRT-"/etc/openmtc/certs/${PKG_NAME}.cert.pem"}
|
|
SSL_KEY=\${SSL_KEY-"/etc/openmtc/certs/${PKG_NAME}.key.pem"}
|
|
SSL_CA=\${SSL_CA-"/etc/openmtc/certs/ca-chain.cert.pem"}
|
|
PORT=\${PORT-"1${APP_PORT_SUFFIX}"}
|
|
|
|
# defaults logging
|
|
LOGGING_FILE=\${LOGGING_FILE-"/var/log/openmtc/${PKG_NAME}.log"}
|
|
LOGGING_LEVEL=\${LOGGING_LEVEL-"ERROR"}
|
|
|
|
# ensure correct level
|
|
case \${LOGGING_LEVEL} in
|
|
FATAL|ERROR|WARN|INFO|DEBUG)
|
|
;;
|
|
*)
|
|
LOGGING_LEVEL="ERROR"
|
|
;;
|
|
esac
|
|
|
|
# local ip
|
|
LOCAL_IP=\$(ip r get 8.8.8.8 | awk 'NR==1 {print \$NF}')
|
|
|
|
# set hostname
|
|
HOST_NAME=\${EXTERNAL_IP-\${LOCAL_IP}}
|
|
|
|
# Configuration of the service.
|
|
CONFIG_TEMP=\${CONFIG_FILE}".tmp"
|
|
echo -n "Configuring M2M ${PKG_NAME}..."
|
|
JQ_STRING='.'
|
|
|
|
# basics
|
|
JQ_STRING=\${JQ_STRING}' |
|
|
.name = "'\${NAME}'" |
|
|
.ep = "'\${EP}'" |
|
|
.cse_base = "'\${CSE_BASE}'" |
|
|
.poas = '\${POAS}' |
|
|
.originator_pre = "'\${ORIGINATOR_PRE}'" |
|
|
.ssl_certs.cert_file = "'\${SSL_CRT}'" |
|
|
.ssl_certs.key_file = "'\${SSL_KEY}'" |
|
|
.ssl_certs.ca_certs = "'\${SSL_CA}'" |
|
|
.port = "'\${PORT}'" |
|
|
.logging.file |= "'\${LOGGING_FILE}'" |
|
|
.logging.level |= "'\${LOGGING_LEVEL}'"
|
|
'
|
|
|
|
cat \${CONFIG_FILE} | jq -M "\${JQ_STRING}"> \${CONFIG_TEMP}
|
|
mv \${CONFIG_TEMP} \${CONFIG_FILE}
|
|
|
|
echo "done"
|
|
|
|
exec python -m ${PKG_NAME} \$@
|
|
EOF
|
|
|
|
if [ ${WEB_APP} == "false" ]; then
|
|
perl -i -n -e 'print unless /PORT=/' "${DOCKER_SCRIPT}"
|
|
perl -i -n -e 'print unless /.port =/' "${DOCKER_SCRIPT}"
|
|
fi
|
|
|
|
if [ ${IN_AE} == "true" ]; then
|
|
perl -i -p -e 's/mn-cse-1/in-cse-1/' "${DOCKER_SCRIPT}"
|
|
perl -i -p -e 's/localhost:8000/localhost:18000/' "${DOCKER_SCRIPT}"
|
|
fi
|
|
|
|
chmod +x "${DOCKER_SCRIPT}"
|
|
|
|
# create docker files
|
|
DOCKER_FILE_AMD64="${DOCKER_FOLDER}/${PKG_NAME}-amd64"
|
|
DOCKER_FILE_ARM="${DOCKER_FOLDER}/${PKG_NAME}-arm"
|
|
cat > "${DOCKER_FILE_AMD64}" << EOF
|
|
############################################################
|
|
# Dockerfile to run openmtc ${PKG_NAME} binary
|
|
############################################################
|
|
|
|
# Set the base image to use openmtc/sdk
|
|
FROM openmtc/sdk-amd64:latest
|
|
|
|
ENV MOD_NAME=${PKG_NAME}
|
|
|
|
# Set the file maintainer
|
|
MAINTAINER rst
|
|
|
|
# install openmtc dependencies
|
|
COPY tmp/\$MOD_NAME-dependencies.txt /tmp/requirements.txt
|
|
RUN pip install --upgrade --requirement /tmp/requirements.txt
|
|
|
|
# install openmtc-${PKG_NAME}
|
|
COPY tmp/openmtc-\$MOD_NAME.tar.gz /tmp/openmtc-\$MOD_NAME.tar.gz
|
|
RUN tar xzf /tmp/openmtc-\$MOD_NAME.tar.gz -C / \\
|
|
--owner root --group root --no-same-owner --no-overwrite-dir \\
|
|
--transform 's/json\.dist/json/' --show-transformed
|
|
|
|
RUN mkdir -p /var/log/openmtc
|
|
|
|
# add change config
|
|
COPY configure-\$MOD_NAME-and-start /usr/local/bin/configure-and-start
|
|
|
|
# entry point
|
|
ENTRYPOINT ["/usr/local/bin/configure-and-start"]
|
|
CMD [""]
|
|
EOF
|
|
|
|
cat "${DOCKER_FILE_AMD64}" | sed 's/-amd64/-arm/g' > "${DOCKER_FILE_ARM}"
|