Refactored platydock and platyvenv
This commit is contained in:
parent
f27e1efdd6
commit
f8d3ea5197
3 changed files with 95 additions and 92 deletions
40
Dockerfile
40
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
|
||||
|
||||
|
|
|
@ -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 <path-to-platypush-config-file>" >&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 <<EOF
|
||||
from platypush.config import Config
|
||||
from platypush.context import get_plugin, get_backend, register_backends
|
||||
|
||||
Config.init('`realpath $cfgfile`')
|
||||
Config.init('`realpath ${cfgfile}`')
|
||||
register_backends()
|
||||
backend_config = Config.get_backends()
|
||||
|
||||
|
@ -68,12 +68,12 @@ EOF
|
|||
)
|
||||
|
||||
while read -r include; do
|
||||
includes+=($include)
|
||||
includes+=(${include})
|
||||
done <<< $(python <<EOF
|
||||
from platypush.config import Config
|
||||
from platypush.context import get_plugin, get_backend, register_backends
|
||||
|
||||
Config.init('`realpath $cfgfile`')
|
||||
Config.init('`realpath ${cfgfile}`')
|
||||
|
||||
for include in Config._included_files:
|
||||
print(include)
|
||||
|
@ -83,13 +83,13 @@ EOF
|
|||
device_id=$(python <<EOF
|
||||
from platypush.config import Config
|
||||
|
||||
Config.init('`realpath $cfgfile`')
|
||||
Config.init('`realpath ${cfgfile}`')
|
||||
print(Config.get('device_id'))
|
||||
EOF
|
||||
)
|
||||
|
||||
envdir=$workdir/$device_id
|
||||
etcdir=$envdir/etc/platypush
|
||||
envdir=${workdir}/${device_id}
|
||||
etcdir=${envdir}/etc/platypush
|
||||
|
||||
echo "Preparing virtual environment for device $device_id"
|
||||
mkdir -p "$envdir"
|
||||
|
@ -105,18 +105,18 @@ EOF
|
|||
done
|
||||
|
||||
cp "$cfgfile" "$etcdir/config.yaml"
|
||||
cfgfile=$etcdir/config.yaml
|
||||
cfgfile=${etcdir}/config.yaml
|
||||
|
||||
python3 -m venv $envdir
|
||||
cd $envdir
|
||||
source $envdir/bin/activate
|
||||
python3 -m venv ${envdir}
|
||||
cd ${envdir}
|
||||
source ${envdir}/bin/activate
|
||||
|
||||
echo "Installing required dependencies"
|
||||
|
||||
for ((i=0; $i < ${#deps[@]}; i++)); do
|
||||
echo ${deps[$i]}
|
||||
done | sort -u | while read dep; do
|
||||
pip install $dep
|
||||
pip install ${dep}
|
||||
done
|
||||
|
||||
pip install --upgrade git+https://github.com/BlackLight/platypush.git
|
||||
|
@ -124,29 +124,29 @@ EOF
|
|||
}
|
||||
|
||||
function start {
|
||||
if [ -z "$1" ]; then
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Usage: $0 start <env-name>" >&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 <env-name>" >&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 <env-name>" >&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 $*;;
|
||||
|
|
|
@ -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 <action> --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:
|
||||
|
|
Loading…
Reference in a new issue