From c7b0e1dcec68155ddbb7550e3a5069297e634783 Mon Sep 17 00:00:00 2001 From: Sylvain Francis Date: Wed, 18 May 2016 17:29:48 +0200 Subject: [PATCH 1/3] Use new async/await syntax --- .../{{cookiecutter.app_name}}/__init__.py | 21 ++++++++----------- .../{{cookiecutter.endpoint_name}}.py | 8 +++---- .../services/{{cookiecutter.service_name}}.py | 11 +++++----- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/__init__.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/__init__.py index 67966b4..734f1c1 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/__init__.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/__init__.py @@ -30,21 +30,19 @@ def __init__(self, *args, **kwargs): '/{{cookiecutter.endpoint_name}}', endpoints.{{cookiecutter.endpoint_name}}.{{cookiecutter.endpoint_name}}) - @asyncio.coroutine - def make_servers(self, sockets): + async def make_servers(self, sockets): # This coroutine is used by api_hour command line to have the list of handlers handlers = {} handler = self.servers['http'].make_handler(logger=self.worker.log, keep_alive=self.worker.cfg.keepalive, access_log=self.worker.log.access_log) for sock in sockets: - srv = yield from self.loop.create_server(handler, sock=sock.sock) + srv = await self.loop.create_server(handler, sock=sock.sock) handlers[srv] = handler return handlers - @asyncio.coroutine - def start(self): - yield from super().start() + async def start(self): + await super().start() LOG.info('Starting engines...') # Add your custom engines here, example with PostgreSQL: self.engines['pg'] = self.loop.create_task(aiopg.create_pool(host=self.config['engines']['pg']['host'], @@ -57,20 +55,19 @@ def start(self): minsize=int(self.config['engines']['pg']['minsize']), maxsize=int(self.config['engines']['pg']['maxsize']), loop=self.loop)) - yield from asyncio.wait([self.engines['pg']], return_when=asyncio.ALL_COMPLETED) + await asyncio.wait([self.engines['pg']], return_when=asyncio.ALL_COMPLETED) LOG.info('All engines ready !') - @asyncio.coroutine - def stop(self): + async def stop(self): LOG.info('Stopping engines...') # Add your custom end here, example with PostgreSQL: if 'pg' in self.engines: if self.engines['pg'].done(): self.engines['pg'].result().terminate() - yield from self.engines['pg'].result().wait_closed() + await self.engines['pg'].result().wait_closed() else: - yield from self.engines['pg'].cancel() + await self.engines['pg'].cancel() LOG.info('All engines stopped !') - yield from super().stop() \ No newline at end of file + await super().stop() \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/endpoints/{{cookiecutter.endpoint_name}}.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/endpoints/{{cookiecutter.endpoint_name}}.py index f1bf0be..4eb03b2 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/endpoints/{{cookiecutter.endpoint_name}}.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/endpoints/{{cookiecutter.endpoint_name}}.py @@ -10,8 +10,7 @@ You handle inputs with outside world here """ -@asyncio.coroutine -def {{cookiecutter.endpoint_name}}(request): +async def {{cookiecutter.endpoint_name}}(request): return JSON({ 'index': 'hello!' }) @@ -20,10 +19,9 @@ def {{cookiecutter.endpoint_name}}(request): # from ..services.{{cookiecutter.service_name}} import get_random_record # -# @asyncio.coroutine -# def db(request): +# async def db(request): # """Test type 2: Single database query""" # container = request.app['ah_container'] # -# return JSON((yield from get_random_record(container))) +# return JSON((await get_random_record(container))) # diff --git a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/services/{{cookiecutter.service_name}}.py b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/services/{{cookiecutter.service_name}}.py index 8ed1a33..2e887ad 100644 --- a/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/services/{{cookiecutter.service_name}}.py +++ b/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}/services/{{cookiecutter.service_name}}.py @@ -5,12 +5,11 @@ You can add your business logic here """ -@asyncio.coroutine -def get_random_record(container): - pg = yield from container.engines['pg'] +async def get_random_record(container): + pg = await container.engines['pg'] - with (yield from pg.cursor()) as cur: - yield from cur.execute('SELECT id AS "Id", randomnumber AS "RandomNumber" FROM world WHERE id=%(idx)s LIMIT 1', + with (await pg.cursor()) as cur: + await cur.execute('SELECT id AS "Id", randomnumber AS "RandomNumber" FROM world WHERE id=%(idx)s LIMIT 1', {'idx': randint(1, 10000)}) - world = yield from cur.fetchone() + world = await cur.fetchone() return world From eabd0931ddf00af453899f0c7d2f854c17c65dbf Mon Sep 17 00:00:00 2001 From: Sylvain Francis Date: Wed, 18 May 2016 20:03:48 +0200 Subject: [PATCH 2/3] Update python version everywhere --- {{cookiecutter.app_name}}/README.rst | 4 ++-- {{cookiecutter.app_name}}/ansible/install.yml | 2 +- {{cookiecutter.app_name}}/ansible/update.yml | 2 +- .../etc/{{cookiecutter.app_name}}/api_hour/logging.ini | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.app_name}}/README.rst b/{{cookiecutter.app_name}}/README.rst index b4414ec..11186fc 100644 --- a/{{cookiecutter.app_name}}/README.rst +++ b/{{cookiecutter.app_name}}/README.rst @@ -23,11 +23,11 @@ Manual install -------------- #. Follow pythonz install doc: https://github.com/saghul/pythonz -#. pythonz install 3.4.3 +#. pythonz install 3.5.1 #. cd /opt #. Git clone your app here #. cd /opt/{{cookiecutter.app_name}}/ -#. /usr/local/pythonz/pythons/CPython-3.4.3/bin/pyvenv pyvenv +#. /usr/local/pythonz/pythons/CPython-3.5.1/bin/pyvenv pyvenv #. . pyvenv/bin/activate #. pip install -r requirements.txt #. cd /etc/init.d/ && ln -s /opt/{{cookiecutter.app_name}}/etc/init.d/{{cookiecutter.app_name}} diff --git a/{{cookiecutter.app_name}}/ansible/install.yml b/{{cookiecutter.app_name}}/ansible/install.yml index 7b406bc..60c4309 100644 --- a/{{cookiecutter.app_name}}/ansible/install.yml +++ b/{{cookiecutter.app_name}}/ansible/install.yml @@ -22,7 +22,7 @@ - name: Install requirements pip: requirements=/opt/{{cookiecutter.app_name}}/requirements.txt virtualenv=/opt/{{cookiecutter.app_name}}/pyvenv - virtualenv_command=/usr/local/pythonz/pythons/CPython-3.4.3/bin/pyvenv + virtualenv_command=/usr/local/pythonz/pythons/CPython-3.5.1/bin/pyvenv - name: Create log dir file: dest=/var/log/{{cookiecutter.app_name}} owner=root group=root state=directory diff --git a/{{cookiecutter.app_name}}/ansible/update.yml b/{{cookiecutter.app_name}}/ansible/update.yml index 22351fb..a5c3610 100644 --- a/{{cookiecutter.app_name}}/ansible/update.yml +++ b/{{cookiecutter.app_name}}/ansible/update.yml @@ -14,7 +14,7 @@ - name: Install requirements pip: requirements=/opt/{{cookiecutter.app_name}}/requirements.txt virtualenv=/opt/{{cookiecutter.app_name}}/pyvenv - virtualenv_command=/usr/local/pythonz/pythons/CPython-3.4.3/bin/pyvenv + virtualenv_command=/usr/local/pythonz/pythons/CPython-3.5.1/bin/pyvenv - name: Restart the service service: name={{cookiecutter.app_name}} state=restarted diff --git a/{{cookiecutter.app_name}}/etc/{{cookiecutter.app_name}}/api_hour/logging.ini b/{{cookiecutter.app_name}}/etc/{{cookiecutter.app_name}}/api_hour/logging.ini index a7fa37c..433c98f 100644 --- a/{{cookiecutter.app_name}}/etc/{{cookiecutter.app_name}}/api_hour/logging.ini +++ b/{{cookiecutter.app_name}}/etc/{{cookiecutter.app_name}}/api_hour/logging.ini @@ -34,7 +34,7 @@ formatter=detailed level=WARN handlers=console,syslog -# https://docs.python.org/3.4/library/warnings.html +# https://docs.python.org/3.5/library/warnings.html [logger_pywarnings] level=WARN handlers=console,syslog From 5b30c039afabc6f14c4b628194d8c59d5cf239ac Mon Sep 17 00:00:00 2001 From: Sylvain Francis Date: Fri, 3 Feb 2017 10:23:26 +0100 Subject: [PATCH 3/3] Add SystemD unit file, remove old SysV files --- .../etc/default/{{cookiecutter.app_name}} | 3 - .../etc/init.d/{{cookiecutter.app_name}} | 80 ----------- .../etc/logrotate.d/{{cookiecutter.app_name}} | 7 - .../monit/conf.d/{{cookiecutter.app_name}} | 5 - {{cookiecutter.app_name}}/etc/rsyslog.conf | 126 ------------------ .../system/{{cookiecutter.app_name}}.service | 10 ++ 6 files changed, 10 insertions(+), 221 deletions(-) delete mode 100644 {{cookiecutter.app_name}}/etc/default/{{cookiecutter.app_name}} delete mode 100755 {{cookiecutter.app_name}}/etc/init.d/{{cookiecutter.app_name}} delete mode 100644 {{cookiecutter.app_name}}/etc/logrotate.d/{{cookiecutter.app_name}} delete mode 100644 {{cookiecutter.app_name}}/etc/monit/conf.d/{{cookiecutter.app_name}} delete mode 100644 {{cookiecutter.app_name}}/etc/rsyslog.conf create mode 100644 {{cookiecutter.app_name}}/etc/systemd/system/{{cookiecutter.app_name}}.service diff --git a/{{cookiecutter.app_name}}/etc/default/{{cookiecutter.app_name}} b/{{cookiecutter.app_name}}/etc/default/{{cookiecutter.app_name}} deleted file mode 100644 index 475c2f0..0000000 --- a/{{cookiecutter.app_name}}/etc/default/{{cookiecutter.app_name}} +++ /dev/null @@ -1,3 +0,0 @@ -# Start the daemon by default, let the user disable it. -START_DAEMON=yes -DAEMON_ARGS="--config_dir=/etc/{{cookiecutter.app_name}} -ac --chdir=/opt/{{cookiecutter.app_name}} {{cookiecutter.app_name}}:Container" diff --git a/{{cookiecutter.app_name}}/etc/init.d/{{cookiecutter.app_name}} b/{{cookiecutter.app_name}}/etc/init.d/{{cookiecutter.app_name}} deleted file mode 100755 index 1390c6d..0000000 --- a/{{cookiecutter.app_name}}/etc/init.d/{{cookiecutter.app_name}} +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# -### BEGIN INIT INFO -# Provides: {{cookiecutter.app_name}} -# Required-Start: $local_fs $remote_fs $network $syslog -# Required-Stop: $local_fs $remote_fs $network $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Startup daemon script for {{cookiecutter.app_name}} -### END INIT INFO -# -# Author: Ludovic Gasc -set -e - -EXECUTABLE_PATH=/opt/{{cookiecutter.app_name}}/pyvenv/bin -PATH=$EXECUTABLE_PATH:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin -DAEMONNAME={{cookiecutter.app_name}} -RUNDIR=/run/$DAEMONNAME -DAEMON=$EXECUTABLE_PATH/api_hour -PIDFILE=/run/lock/${DAEMONNAME}.pid -DAEMON_ARGS="" - -# Exit if the package is not installed -[ -x "$DAEMON" ] || exit 0 - -# Create RUNDIR if it doesn't exist -[ -d "$RUNDIR" ] || mkdir -p "$RUNDIR" - -# Read configuration variable file if it is present -[ -r /etc/default/$DAEMONNAME ] && . /etc/default/$DAEMONNAME - -# Load the VERBOSE setting and other rcS variables -[ -f /etc/default/rcS ] && . /etc/default/rcS - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. -. /lib/lsb/init-functions - -case "$1" in - start) - log_daemon_msg "Starting" "$DAEMONNAME" - if start-stop-daemon -b --start --pidfile $PIDFILE --startas $DAEMON -- $DAEMON_ARGS; - then - log_end_msg 0 - else - log_end_msg 1 - fi - ;; - stop) - log_daemon_msg "Stopping" "$DAEMONNAME" - if start-stop-daemon --stop --retry 5 --pidfile $PIDFILE; - then - log_end_msg 0 - else - log_end_msg 1 - fi - ;; - reload|force-reload) - log_daemon_msg "Reloading" "$DAEMONNAME" - if start-stop-daemon --stop --signal 1 --pidfile $PIDFILE --startas $DAEMON; - then - log_end_msg 0 - else - log_end_msg 1 - fi - ;; - restart) - $0 stop - $0 start - ;; - status) - status_of_proc -p $PIDFILE "$DAEMON" $DAEMONNAME && exit 0 || exit $? - ;; - *) - echo "Usage: $0 {start|stop|reload|force-reload|restart|status}" - exit 1 - ;; -esac - -exit 0 diff --git a/{{cookiecutter.app_name}}/etc/logrotate.d/{{cookiecutter.app_name}} b/{{cookiecutter.app_name}}/etc/logrotate.d/{{cookiecutter.app_name}} deleted file mode 100644 index 4ae695b..0000000 --- a/{{cookiecutter.app_name}}/etc/logrotate.d/{{cookiecutter.app_name}} +++ /dev/null @@ -1,7 +0,0 @@ -/var/log/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}.log { - daily - rotate 15 - compress - copytruncate - missingok -} \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/etc/monit/conf.d/{{cookiecutter.app_name}} b/{{cookiecutter.app_name}}/etc/monit/conf.d/{{cookiecutter.app_name}} deleted file mode 100644 index 2787ef0..0000000 --- a/{{cookiecutter.app_name}}/etc/monit/conf.d/{{cookiecutter.app_name}} +++ /dev/null @@ -1,5 +0,0 @@ -check process cache_updater with pidfile /run/lock/{{cookiecutter.app_name}}.pid - group {{cookiecutter.app_name}} - start program = "/etc/init.d/{{cookiecutter.app_name}} start" - stop program = "/etc/init.d/{{cookiecutter.app_name}} stop" - if 5 restarts within 5 cycles then timeout \ No newline at end of file diff --git a/{{cookiecutter.app_name}}/etc/rsyslog.conf b/{{cookiecutter.app_name}}/etc/rsyslog.conf deleted file mode 100644 index a483c97..0000000 --- a/{{cookiecutter.app_name}}/etc/rsyslog.conf +++ /dev/null @@ -1,126 +0,0 @@ -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html - - -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging -$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability -$SystemLogRateLimitInterval 1 -$SystemLogRateLimitBurst 1000 - -# provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 - -# provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Where to place spool and state files -# -$WorkDirectory /var/spool/rsyslog - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - - -############### -#### RULES #### -############### - -# -# First some standard log files. Log by facility. -# -auth,authpriv.* /var/log/auth.log -*.*;auth,authpriv.none;\ - local6.none -/var/log/syslog -#cron.* /var/log/cron.log -daemon.* -/var/log/daemon.log -kern.* -/var/log/kern.log -lpr.* -/var/log/lpr.log -mail.* -/var/log/mail.log -user.* -/var/log/user.log - -local6.* /var/log/{{cookiecutter.app_name}}/{{cookiecutter.app_name}}.log - -# -# Logging for the mail system. Split it up so that -# it is easy to write scripts to parse these files. -# -mail.info -/var/log/mail.info -mail.warn -/var/log/mail.warn -mail.err /var/log/mail.err - -# -# Logging for INN news system. -# -news.crit /var/log/news/news.crit -news.err /var/log/news/news.err -news.notice -/var/log/news/news.notice - -# -# Some "catch-all" log files. -# -*.=debug;\ - auth,authpriv.none;\ - news.none;mail.none;local6.none;local7.none -/var/log/debug -*.=info;*.=notice;*.=warn;\ - auth,authpriv.none;\ - cron,daemon.none;\ - mail,news.none;local6.none;local7.none -/var/log/messages - -# -# Emergencies are sent to everybody logged in. -# -*.emerg :omusrmsg:* - -# -# I like to have messages displayed on the console, but only on a virtual -# console I usually leave idle. -# -#daemon,mail.*;\ -# news.=crit;news.=err;news.=notice;\ -# *.=debug;*.=info;\ -# *.=notice;*.=warn /dev/tty8 - -# The named pipe /dev/xconsole is for the `xconsole' utility. To use it, -# you must invoke `xconsole' with the `-file' option: -# -# $ xconsole -file /dev/xconsole [...] -# -# NOTE: adjust the list below, or you'll go crazy if you have a reasonably -# busy site.. -# -daemon.*;mail.*;\ - news.err;\ - *.=debug;*.=info;\ - *.=notice;*.=warn |/dev/xconsole diff --git a/{{cookiecutter.app_name}}/etc/systemd/system/{{cookiecutter.app_name}}.service b/{{cookiecutter.app_name}}/etc/systemd/system/{{cookiecutter.app_name}}.service new file mode 100644 index 0000000..1f2702e --- /dev/null +++ b/{{cookiecutter.app_name}}/etc/systemd/system/{{cookiecutter.app_name}}.service @@ -0,0 +1,10 @@ +[Unit] +Description={{cookiecutter.app_name}} +After=network.target + +[Service] +Type=simple +ExecStart=/opt/{{cookiecutter.app_name}}/pyvenv/bin/api_hour --config_dir=/etc/{{cookiecutter.app_name}} -ac --chdir=/opt/{{cookiecutter.app_name}} {{cookiecutter.app_name}}:Container + +[Install] +WantedBy=multi-user.target