From f8d3ea519798c93388da0ebe9114eb448bfe9c9c Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Sun, 1 Dec 2019 22:27:54 +0100 Subject: [PATCH] Refactored platydock and platyvenv --- Dockerfile | 40 ++++++++------- bin/platyvenv | 88 ++++++++++++++++----------------- platypush/platydock/__init__.py | 59 +++++++++++----------- 3 files changed, 95 insertions(+), 92 deletions(-) diff --git a/Dockerfile b/Dockerfile index 79e69b94..d22bed5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,22 @@ -FROM python:alpine3.7 - -RUN mkdir /app -COPY . /app -WORKDIR /app -RUN apk add --update --no-cache --virtual build-base \ - && apk add --update --no-cache libffi-dev \ - && apk add --update --no-cache zlib-dev \ - && apk add --update --no-cache libjpeg-turbo-dev \ - && pip install -r requirements.txt \ - && apk del build-base \ - && apk del libffi-dev \ - && apk del libjpeg-turbo-dev \ - && apk del zlib-dev - -RUN cd /app && python setup.py build install -CMD python -m platypush - +# Sample Dockerfile. Use platydock -c /path/to/custom/config.yamlr +# to generate your custom Dockerfile. + + +FROM python:alpine3.7 + +RUN mkdir /app +COPY . /app +WORKDIR /app +RUN apk add --update --no-cache --virtual build-base \ + && apk add --update --no-cache libffi-dev \ + && apk add --update --no-cache zlib-dev \ + && apk add --update --no-cache libjpeg-turbo-dev \ + && pip install -r requirements.txt \ + && apk del build-base \ + && apk del libffi-dev \ + && apk del libjpeg-turbo-dev \ + && apk del zlib-dev + +RUN cd /app && python setup.py build install +CMD python -m platypush + diff --git a/bin/platyvenv b/bin/platyvenv index c2dcbc92..60e14e29 100755 --- a/bin/platyvenv +++ b/bin/platyvenv @@ -17,7 +17,7 @@ function build { cfgfile= while getopts ':c:' opt; do - case $opt in + case ${opt} in c) cfgfile=$OPTARG;; \?) @@ -29,7 +29,7 @@ function build { esac done - if [ -z "$cfgfile" ]; then + if [[ -z "$cfgfile" ]]; then echo "Usage: $0 build -c " >&2 exit 1 fi @@ -39,18 +39,18 @@ function build { includes=() while read -r line; do - echo $line | egrep '``pip install .+?``' > /dev/null 2>&1 + echo ${line} | egrep '``pip install .+?``' > /dev/null 2>&1 if (( $? != 0 )); then continue fi - dep=$(echo $line | sed -r -e 's/.*``pip install (.+?)``.*/\1/') + dep=$(echo ${line} | sed -r -e 's/.*``pip install (.+?)``.*/\1/') deps+=("$dep") done <<< $(python <" >&2 exit 1 fi env=$1 - envdir=$workdir/$env - logsdir=$envdir/var/log/platypush - rundir=$envdir/var/run - pidfile=$rundir/platypush.pid - cfgfile=$envdir/etc/platypush/config.yaml + envdir=${workdir}/${env} + logsdir=${envdir}/var/log/platypush + rundir=${envdir}/var/run + pidfile=${rundir}/platypush.pid + cfgfile=${envdir}/etc/platypush/config.yaml - if [ ! -d "$envdir" ]; then + if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi - mkdir -p $logsdir - mkdir -p $rundir + mkdir -p ${logsdir} + mkdir -p ${rundir} if [[ -f "$pidfile" ]]; then pid=`cat "$pidfile"` - if ps -p $pid | grep platypush; then + if ps -p ${pid} | grep platypush; then echo "Another instance (PID $pid) is running, please stop that instance first" exit 1 fi @@ -155,10 +155,10 @@ function start { rm -f "$pidfile" fi - python3 -m venv $envdir - cd $envdir + python3 -m venv ${envdir} + cd ${envdir} source bin/activate - bin/platypush -c "$cfgfile" -P "$pidfile" > $logsdir/stdout.log 2> $logsdir/stderr.log & + bin/platypush -c "$cfgfile" -P "$pidfile" > ${logsdir}/stdout.log 2> ${logsdir}/stderr.log & start_time=`date +'%s'` timeout=30 @@ -166,7 +166,7 @@ function start { [[ -f "$pidfile" ]] && break now=`date +'%s'` let elapsed=$now-$start_time - if (( $elapsed >= $timeout )); then + if (( ${elapsed} >= ${timeout} )); then echo "Platypush instance '$env' didn't start within $timeout seconds" >&2 exit 1 fi @@ -181,44 +181,44 @@ function start { } function stop { - if [ -z "$1" ]; then + if [[ -z "$1" ]]; then echo "Usage: $0 stop " >&2 exit 1 fi env=$1 - envdir=$workdir/$env - rundir=$envdir/var/run - pidfile=$rundir/platypush.pid + envdir=${workdir}/${env} + rundir=${envdir}/var/run + pidfile=${rundir}/platypush.pid - if [ ! -d "$envdir" ]; then + if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi if [[ ! -f "$pidfile" ]]; then - echo "No pidfile found for instance "$env"" + echo "No pidfile found for instance "${env}"" exit 1 fi pid=`cat "$pidfile"` pids="$pid `ps --no-headers -o pid= --ppid $pid`" - kill -9 $pids + kill -9 ${pids} rm -f "$pidfile" echo "Instance '$env' with PID $pid stopped" } function rme { - if [ -z "$1" ]; then + if [[ -z "$1" ]]; then echo "Usage: $0 rm " >&2 exit 1 fi - envdir=$workdir/$1 - rundir=$envdir/var/run - pidfile=$rundir/platypush.pid + envdir=${workdir}/$1 + rundir=${envdir}/var/run + pidfile=${rundir}/platypush.pid - if [ ! -d "$envdir" ]; then + if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi @@ -247,10 +247,10 @@ fi action=$1 shift -mkdir -p $workdir +mkdir -p ${workdir} -case $action in - 'build') build $*;; +case ${action} in + 'build') build;; 'start') start $*;; 'stop') stop $*;; 'rm') rme $*;; diff --git a/platypush/platydock/__init__.py b/platypush/platydock/__init__.py index a7cac7e3..4c073151 100755 --- a/platypush/platydock/__init__.py +++ b/platypush/platydock/__init__.py @@ -17,21 +17,19 @@ import sys import textwrap import traceback as tb -import platypush - from platypush.config import Config from platypush.context import register_backends, get_plugin, get_backend - workdir = os.path.join(os.path.expanduser('~'), '.local', 'share', - 'platypush', 'platydock') + 'platypush', 'platydock') + class Action(enum.Enum): build = 'build' start = 'start' - stop = 'stop' - rm = 'rm' - ls = 'ls' + stop = 'stop' + rm = 'rm' + ls = 'ls' def __str__(self): return self.value @@ -47,30 +45,28 @@ def _parse_deps(cls): return deps -def generate_dockerfile(deps, ports, cfgfile, devdir): + +def generate_dockerfile(deps, ports, cfgfile, devdir, python_version): device_id = Config.get('device_id') if not device_id: raise RuntimeError(('You need to specify a device_id in {} - Docker ' + - 'containers cannot rely on hostname').format(cfgfile)) - - try: - os.makedirs(devdir) - except FileExistsError: - pass + 'containers cannot rely on hostname').format(cfgfile)) + os.makedirs(devdir, exist_ok=True) content = textwrap.dedent( ''' - FROM python:alpine3.7 + FROM python:alpine{python_version} RUN mkdir -p /etc/platypush RUN mkdir -p /usr/local/share/platypush\n - ''').lstrip() + '''.format(python_version=python_version)).lstrip() srcdir = os.path.dirname(cfgfile) cfgfile_copy = os.path.join(devdir, 'config.yaml') subprocess.call(['cp', cfgfile, cfgfile_copy]) content += 'COPY config.yaml /etc/platypush/\n' + # noinspection PyProtectedMember for include in Config._included_files: incdir = os.path.relpath(os.path.dirname(include), srcdir) destdir = os.path.join(devdir, incdir) @@ -83,8 +79,7 @@ def generate_dockerfile(deps, ports, cfgfile, devdir): subprocess.call(['cp', include, destdir]) content += 'RUN mkdir -p /etc/platypush/' + incdir + '\n' content += 'COPY ' + os.path.relpath(include, srcdir) + \ - ' /etc/platypush/' + incdir + '\n' - + ' /etc/platypush/' + incdir + '\n' content += textwrap.dedent( ''' @@ -96,7 +91,7 @@ def generate_dockerfile(deps, ports, cfgfile, devdir): content += '\t&& pip install {} \\\n'.format(dep) content += '\t&& pip install ' + \ - 'git+https://github.com/BlackLight/platypush.git \\\n' + 'git+https://github.com/BlackLight/platypush.git \\\n' content += '\t&& apk del git \\\n' content += '\t&& apk del build-base\n\n' @@ -120,14 +115,17 @@ def build(args): parser = argparse.ArgumentParser(prog='platydock build', description='Build a Platypush image ' + - 'from a config.yaml') + 'from a config.yaml') parser.add_argument('-c', '--config', type=str, required=True, help='Path to the platypush configuration file') + parser.add_argument('-p', '--python-version', type=str, default='3.8', + help='Python version to be used') opts, args = parser.parse_known_args(args) cfgfile = os.path.abspath(os.path.expanduser(opts.config)) + python_version = opts.python_version Config.init(cfgfile) register_backends() backend_config = Config.get_backends() @@ -150,11 +148,11 @@ def build(args): for name in Config.get_plugins().keys(): try: deps.update(_parse_deps(get_plugin(name))) - except: - pass + except Exception as ex: + print('Dependencies parsing error for {}: {}'.format(name, str(ex))) devdir = os.path.join(workdir, Config.get('device_id')) - generate_dockerfile(deps=deps, ports=ports, cfgfile=cfgfile, devdir=devdir) + generate_dockerfile(deps=deps, ports=ports, cfgfile=cfgfile, devdir=devdir, python_version=python_version) subprocess.call(['docker', 'build', '-t', 'platypush-{}'.format( Config.get('device_id')), devdir]) @@ -164,8 +162,8 @@ def start(args): global workdir parser = argparse.ArgumentParser(prog='platydock start', - description='Start a Platypush container', - epilog=textwrap.dedent(''' + description='Start a Platypush container', + epilog=textwrap.dedent(''' You can append additional options that will be passed to the docker container. Example: @@ -239,9 +237,9 @@ def rm(args): parser = argparse.ArgumentParser(prog='platydock rm', description='Remove a Platypush image. ' + - 'NOTE: make sure that no container is ' + - 'running nor linked to the image before ' + - 'removing it') + 'NOTE: make sure that no container is ' + + 'running nor linked to the image before ' + + 'removing it') parser.add_argument('image', type=str, help='Platypush image to remove') opts, args = parser.parse_known_args(args) @@ -274,12 +272,14 @@ def ls(args): for image in images: print(image) + def main(): parser = argparse.ArgumentParser(prog='platydock', add_help=False, description='Manage Platypush docker containers', epilog='Use platydock --help to ' + - 'get additional help') + 'get additional help') + # noinspection PyTypeChecker parser.add_argument('action', nargs='?', type=Action, choices=list(Action), help='Action to execute') parser.add_argument('-h', '--help', action='store_true', help='Show usage') @@ -302,5 +302,4 @@ if __name__ == '__main__': tb.print_exc(file=sys.stdout) print(ERR_PREFIX + str(e) + ERR_SUFFIX, file=sys.stderr) - # vim:sw=4:ts=4:et: