mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
[wip] Add a test service
This commit is contained in:
parent
6692ed8345
commit
fe8fdec06f
4 changed files with 339 additions and 0 deletions
188
bin/test-moulinette-api
Executable file
188
bin/test-moulinette-api
Executable file
|
@ -0,0 +1,188 @@
|
||||||
|
#! /usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
# Either we are in a development environment or not
|
||||||
|
IN_DEVEL = False
|
||||||
|
|
||||||
|
# Default server configuration
|
||||||
|
DEFAULT_HOST = 'localhost'
|
||||||
|
DEFAULT_PORT = 6787
|
||||||
|
|
||||||
|
# Level for which loggers will log
|
||||||
|
LOGGERS_LEVEL = 'INFO'
|
||||||
|
|
||||||
|
# Handlers that will be used by loggers
|
||||||
|
# - file: log to the file LOG_DIR/LOG_FILE
|
||||||
|
# - api: serve logs through the api
|
||||||
|
# - console: log to stderr
|
||||||
|
LOGGERS_HANDLERS = ['file', 'api']
|
||||||
|
|
||||||
|
# Directory and file to be used by logging
|
||||||
|
LOG_DIR = '/var/log/test'
|
||||||
|
LOG_FILE = 'test-api.log'
|
||||||
|
|
||||||
|
# Check and load - as needed - development environment
|
||||||
|
if not __file__.startswith('/usr/'):
|
||||||
|
IN_DEVEL = True
|
||||||
|
if IN_DEVEL:
|
||||||
|
basedir = os.path.abspath('%s/../' % os.path.dirname(__file__))
|
||||||
|
if os.path.isdir(os.path.join(basedir, 'moulinette')):
|
||||||
|
sys.path.insert(0, basedir)
|
||||||
|
LOG_DIR = os.path.join(basedir, 'log')
|
||||||
|
|
||||||
|
|
||||||
|
import moulinette
|
||||||
|
from moulinette.actionsmap import ActionsMap
|
||||||
|
from moulinette.interfaces.cli import colorize
|
||||||
|
|
||||||
|
|
||||||
|
# Initialization & helpers functions -----------------------------------
|
||||||
|
|
||||||
|
def _die(message, title='Error:'):
|
||||||
|
"""Print error message and exit"""
|
||||||
|
print('%s %s' % (colorize(title, 'red'), message))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def _parse_api_args():
|
||||||
|
"""Parse main arguments for the api"""
|
||||||
|
parser = argparse.ArgumentParser(add_help=False,
|
||||||
|
description="Run the YunoHost API to manage your server.",
|
||||||
|
)
|
||||||
|
srv_group = parser.add_argument_group('server configuration')
|
||||||
|
srv_group.add_argument('-h', '--host',
|
||||||
|
action='store', default=DEFAULT_HOST,
|
||||||
|
help="Host to listen on (default: %s)" % DEFAULT_HOST,
|
||||||
|
)
|
||||||
|
srv_group.add_argument('-p', '--port',
|
||||||
|
action='store', default=DEFAULT_PORT, type=int,
|
||||||
|
help="Port to listen on (default: %d)" % DEFAULT_PORT,
|
||||||
|
)
|
||||||
|
srv_group.add_argument('--no-websocket',
|
||||||
|
action='store_true', default=True, dest='use_websocket',
|
||||||
|
help="Serve without WebSocket support, used to handle "
|
||||||
|
"asynchronous responses such as the messages",
|
||||||
|
)
|
||||||
|
glob_group = parser.add_argument_group('global arguments')
|
||||||
|
glob_group.add_argument('--no-cache',
|
||||||
|
action='store_false', default=True, dest='use_cache',
|
||||||
|
help="Don't use actions map cache",
|
||||||
|
)
|
||||||
|
glob_group.add_argument('--debug',
|
||||||
|
action='store_true', default=False,
|
||||||
|
help="Set log level to DEBUG",
|
||||||
|
)
|
||||||
|
glob_group.add_argument('--verbose',
|
||||||
|
action='store_true', default=False,
|
||||||
|
help="Be verbose in the output",
|
||||||
|
)
|
||||||
|
glob_group.add_argument('--help',
|
||||||
|
action='help', help="Show this help message and exit",
|
||||||
|
)
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def _init_moulinette(use_websocket=True, debug=False, verbose=False):
|
||||||
|
"""Configure logging and initialize the moulinette"""
|
||||||
|
# Define loggers handlers
|
||||||
|
handlers = set(LOGGERS_HANDLERS)
|
||||||
|
if not use_websocket and 'api' in handlers:
|
||||||
|
handlers.remove('api')
|
||||||
|
if verbose and 'console' not in handlers:
|
||||||
|
handlers.add('console')
|
||||||
|
root_handlers = handlers - set(['api'])
|
||||||
|
|
||||||
|
# Define loggers level
|
||||||
|
level = LOGGERS_LEVEL
|
||||||
|
if debug:
|
||||||
|
level = 'DEBUG'
|
||||||
|
|
||||||
|
# Custom logging configuration
|
||||||
|
logging = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': True,
|
||||||
|
'formatters': {
|
||||||
|
'console': {
|
||||||
|
'format': '%(relativeCreated)-5d %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s'
|
||||||
|
},
|
||||||
|
'precise': {
|
||||||
|
'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'filters': {
|
||||||
|
'action': {
|
||||||
|
'()': 'moulinette.utils.log.ActionFilter',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'api': {
|
||||||
|
'class': 'moulinette.interfaces.api.APIQueueHandler',
|
||||||
|
},
|
||||||
|
'file': {
|
||||||
|
'class': 'logging.handlers.WatchedFileHandler',
|
||||||
|
'formatter': 'precise',
|
||||||
|
'filename': '%s/%s' % (LOG_DIR, LOG_FILE),
|
||||||
|
'filters': ['action'],
|
||||||
|
},
|
||||||
|
'console': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'console',
|
||||||
|
'stream': 'ext://sys.stdout',
|
||||||
|
'filters': ['action'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'yunohost': {
|
||||||
|
'level': level,
|
||||||
|
'handlers': handlers,
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'moulinette': {
|
||||||
|
'level': level,
|
||||||
|
'handlers': [],
|
||||||
|
'propagate': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'root': {
|
||||||
|
'level': level,
|
||||||
|
'handlers': root_handlers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create log directory
|
||||||
|
if not os.path.isdir(LOG_DIR):
|
||||||
|
try:
|
||||||
|
os.makedirs(LOG_DIR, 0750)
|
||||||
|
except os.error as e:
|
||||||
|
_die(str(e))
|
||||||
|
|
||||||
|
# Initialize moulinette
|
||||||
|
moulinette.init(logging_config=logging, _from_source=IN_DEVEL)
|
||||||
|
|
||||||
|
def _retrieve_namespaces():
|
||||||
|
"""Return the list of namespaces to load"""
|
||||||
|
ret = ['test']
|
||||||
|
for n in ActionsMap.get_namespaces():
|
||||||
|
# Append YunoHost modules
|
||||||
|
if n.startswith('test_'):
|
||||||
|
ret.append(n)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
# Main action ----------------------------------------------------------
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
opts = _parse_api_args()
|
||||||
|
_init_moulinette(opts.use_websocket, opts.debug, opts.verbose)
|
||||||
|
|
||||||
|
# Run the server
|
||||||
|
from yunohost.utils.packages import ynh_packages_version
|
||||||
|
ret = moulinette.api(
|
||||||
|
_retrieve_namespaces(),
|
||||||
|
host=opts.host, port=opts.port, routes={
|
||||||
|
}, use_cache=opts.use_cache, use_websocket=opts.use_websocket
|
||||||
|
)
|
||||||
|
sys.exit(ret)
|
4
debian/test-moulinette-api.default
vendored
Normal file
4
debian/test-moulinette-api.default
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Override yunohost-api options.
|
||||||
|
# Example to log debug: DAEMON_OPTS="--debug"
|
||||||
|
#
|
||||||
|
#DAEMON_OPTS=""
|
132
debian/test-moulinette-api.init
vendored
Normal file
132
debian/test-moulinette-api.init
vendored
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: yunohost-api
|
||||||
|
# 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: Manage YunoHost API Server
|
||||||
|
# Description: Manage YunoHost API Server
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DESC="test API Server"
|
||||||
|
NAME="test-moulinette-api"
|
||||||
|
DAEMON=/usr/bin/$NAME
|
||||||
|
DAEMON_OPTS=""
|
||||||
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||||
|
PIDFILE=/var/run/$NAME.pid
|
||||||
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
LOGFILE=/var/log/$NAME.log
|
||||||
|
|
||||||
|
# Include yunohost-api defaults if available
|
||||||
|
if [ -r /etc/default/test-moulinette-api ]; then
|
||||||
|
. /etc/default/test-moulinette-api
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Exit if the package is not installed
|
||||||
|
[ -x "$DAEMON" ] || exit 0
|
||||||
|
|
||||||
|
# Load the VERBOSE setting and other rcS variables
|
||||||
|
. /lib/init/vars.sh
|
||||||
|
|
||||||
|
# Define LSB log_* functions.
|
||||||
|
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||||
|
# and status_of_proc is working.
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that starts the daemon/service
|
||||||
|
#
|
||||||
|
do_start()
|
||||||
|
{
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been started
|
||||||
|
# 1 if daemon was already running
|
||||||
|
# 2 if daemon could not be started
|
||||||
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||||
|
|| return 1
|
||||||
|
start-stop-daemon --start --background --make-pidfile --quiet --no-close \
|
||||||
|
--pidfile $PIDFILE --exec $DAEMON -- \
|
||||||
|
$DAEMON_OPTS >>$LOGFILE 2>&1 \
|
||||||
|
|| return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that stops the daemon/service
|
||||||
|
#
|
||||||
|
do_stop()
|
||||||
|
{
|
||||||
|
# Return
|
||||||
|
# 0 if daemon has been stopped
|
||||||
|
# 1 if daemon was already stopped
|
||||||
|
# 2 if daemon could not be stopped
|
||||||
|
# other if a failure occurred
|
||||||
|
start-stop-daemon --stop --oknodo --pidfile $PIDFILE
|
||||||
|
RETVAL="$?"
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
return "$RETVAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function that sends a SIGHUP to the daemon/service
|
||||||
|
#
|
||||||
|
do_reload() {
|
||||||
|
# Send a SIGHUP to reload the daemon.
|
||||||
|
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||||
|
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||||
|
;;
|
||||||
|
reload)
|
||||||
|
log_daemon_msg "Reloading $DESC" "$NAME"
|
||||||
|
do_reload
|
||||||
|
log_end_msg $?
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
case "$?" in
|
||||||
|
0|1)
|
||||||
|
do_start
|
||||||
|
case "$?" in
|
||||||
|
0) log_end_msg 0 ;;
|
||||||
|
1) log_end_msg 1 ;; # Old process is still running
|
||||||
|
*) log_end_msg 1 ;; # Failed to start
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Failed to stop
|
||||||
|
log_end_msg 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload}" >&2
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
:
|
15
debian/test-moulinette-api.service
vendored
Normal file
15
debian/test-moulinette-api.service
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Test API Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment=DAEMON_OPTS=
|
||||||
|
EnvironmentFile=-/etc/default/test-moulinette-api
|
||||||
|
ExecStart=/usr/bin/test-moulinette-api $DAEMON_OPTS
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
Restart=always
|
||||||
|
RestartSec=1
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
Add table
Reference in a new issue