yunohost/bin/yunohost-api
2020-05-07 22:15:51 +02:00

145 lines
4.3 KiB
Python
Executable file

#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import argparse
import moulinette
from moulinette.actionsmap import ActionsMap
from moulinette.interfaces.cli import colorize
# Default server configuration
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 6787
# Directory and file to be used by logging
LOG_DIR = '/var/log/yunohost'
LOG_FILE = 'yunohost-api.log'
# 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,
)
glob_group = parser.add_argument_group('global arguments')
glob_group.add_argument('--debug',
action='store_true', default=False,
help="Set log level to DEBUG",
)
glob_group.add_argument('--help',
action='help', help="Show this help message and exit",
)
return parser.parse_args()
def _init_moulinette(debug=False):
"""Configure logging and initialize the moulinette"""
# Create log directory
if not os.path.isdir(LOG_DIR):
try:
os.makedirs(LOG_DIR, 0750)
except os.error as e:
_die(str(e))
# 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': {
'level': 'DEBUG' if debug else 'INFO',
'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': 'DEBUG',
'handlers': ['file', 'api'] + ['console'] if debug else [],
'propagate': False,
},
'moulinette': {
'level': 'DEBUG',
'handlers': [],
'propagate': True,
},
},
'root': {
'level': 'DEBUG',
'handlers': ['file'] + ['console'] if debug else [],
},
}
# Initialize moulinette
moulinette.init(logging_config=logging)
def _retrieve_namespaces():
"""Return the list of namespaces to load"""
extensions = [n for n in ActionsMap.get_namespaces() if n.startswith('ynh_')]
return ['yunohost'] + extensions
# Callbacks for additional routes --------------------------------------
def is_installed():
""" Check whether YunoHost is installed or not """
return { 'installed': os.path.isfile('/etc/yunohost/installed') }
# Main action ----------------------------------------------------------
if __name__ == '__main__':
opts = _parse_api_args()
_init_moulinette(opts.use_websocket, opts.debug, opts.verbose)
# Run the server
ret = moulinette.api(
_retrieve_namespaces(),
host=opts.host,
port=opts.port,
routes={ ('GET', '/installed'): is_installed, },
use_websocket=True
)
sys.exit(ret)