mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
208 lines
6 KiB
Python
Executable file
208 lines
6 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import sys
|
|
import os
|
|
|
|
# Either we are in a development environment or not
|
|
IN_DEVEL = False
|
|
|
|
# Level for which loggers will log
|
|
LOGGERS_LEVEL = 'INFO'
|
|
TTY_LOG_LEVEL = 'SUCCESS'
|
|
|
|
# Handlers that will be used by loggers
|
|
# - file: log to the file LOG_DIR/LOG_FILE
|
|
# - tty: log to current tty
|
|
LOGGERS_HANDLERS = ['file', 'tty']
|
|
|
|
# Directory and file to be used by logging
|
|
LOG_DIR = '/var/log/yunohost'
|
|
LOG_FILE = 'yunohost-cli.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')
|
|
|
|
|
|
# Initialization & helpers functions -----------------------------------
|
|
|
|
def _die(message, title='Error:'):
|
|
"""Print error message and exit"""
|
|
try:
|
|
from moulinette.interfaces.cli import colorize
|
|
except ImportError:
|
|
colorize = lambda msg, c: msg
|
|
print('%s %s' % (colorize(title, 'red'), message))
|
|
sys.exit(1)
|
|
|
|
def _parse_cli_args():
|
|
"""Parse additional arguments for the cli"""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
parser.add_argument('--no-cache',
|
|
action='store_false', default=True, dest='use_cache',
|
|
help="Don't use actions map cache",
|
|
)
|
|
parser.add_argument('--output-as',
|
|
choices=['json', 'plain'], default=None,
|
|
help="Output result in another format",
|
|
)
|
|
parser.add_argument('--debug',
|
|
action='store_true', default=False,
|
|
help="Log and print debug messages",
|
|
)
|
|
parser.add_argument('--verbose',
|
|
action='store_true', default=False,
|
|
help="Be more verbose in the output",
|
|
)
|
|
parser.add_argument('--quiet',
|
|
action='store_true', default=False,
|
|
help="Don't produce any output",
|
|
)
|
|
parser.add_argument('--admin-password',
|
|
default=None, dest='password', metavar='PASSWORD',
|
|
help="The admin password to use to authenticate",
|
|
)
|
|
# deprecated arguments
|
|
parser.add_argument('--plain',
|
|
action='store_true', default=False, help=argparse.SUPPRESS
|
|
)
|
|
parser.add_argument('--json',
|
|
action='store_true', default=False, help=argparse.SUPPRESS
|
|
)
|
|
|
|
opts, args = parser.parse_known_args()
|
|
|
|
# output compatibility
|
|
if opts.plain:
|
|
opts.output_as = 'plain'
|
|
elif opts.json:
|
|
opts.output_as = 'json'
|
|
|
|
return (parser, opts, args)
|
|
|
|
def _init_moulinette(debug=False, verbose=False, quiet=False):
|
|
"""Configure logging and initialize the moulinette"""
|
|
from moulinette import init
|
|
|
|
# Define loggers handlers
|
|
handlers = set(LOGGERS_HANDLERS)
|
|
if quiet and 'tty' in handlers:
|
|
handlers.remove('tty')
|
|
elif verbose and 'tty' not in handlers:
|
|
handlers.append('tty')
|
|
|
|
root_handlers = set(handlers)
|
|
if not debug:
|
|
root_handlers.remove('tty')
|
|
|
|
# Define loggers level
|
|
level = LOGGERS_LEVEL
|
|
tty_level = TTY_LOG_LEVEL
|
|
if verbose:
|
|
tty_level = 'INFO'
|
|
if debug:
|
|
tty_level = level = 'DEBUG'
|
|
|
|
# Custom logging configuration
|
|
logging = {
|
|
'version': 1,
|
|
'disable_existing_loggers': True,
|
|
'formatters': {
|
|
'tty-debug': {
|
|
'format': '%(relativeCreated)-4d %(fmessage)s'
|
|
},
|
|
'precise': {
|
|
'format': '%(asctime)-15s %(levelname)-8s %(name)s %(funcName)s - %(fmessage)s'
|
|
},
|
|
},
|
|
'filters': {
|
|
'action': {
|
|
'()': 'moulinette.utils.log.ActionFilter',
|
|
},
|
|
},
|
|
'handlers': {
|
|
'tty': {
|
|
'level': tty_level,
|
|
'class': 'moulinette.interfaces.cli.TTYHandler',
|
|
'formatter': 'tty-debug' if debug else '',
|
|
},
|
|
'file': {
|
|
'class': 'logging.FileHandler',
|
|
'formatter': 'precise',
|
|
'filename': '%s/%s' % (LOG_DIR, LOG_FILE),
|
|
'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
|
|
init(logging_config=logging, _from_source=IN_DEVEL)
|
|
|
|
def _retrieve_namespaces():
|
|
"""Return the list of namespaces to load"""
|
|
from moulinette.actionsmap import ActionsMap
|
|
ret = ['yunohost']
|
|
for n in ActionsMap.get_namespaces():
|
|
# Append YunoHost modules
|
|
if n.startswith('ynh_'):
|
|
ret.append(n)
|
|
return ret
|
|
|
|
|
|
# Main action ----------------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
parser, opts, args = _parse_cli_args()
|
|
_init_moulinette(opts.debug, opts.verbose, opts.quiet)
|
|
|
|
# Check that YunoHost is installed
|
|
if not os.path.isfile('/etc/yunohost/installed') and \
|
|
(len(args) < 2 or (args[0] +' '+ args[1] != 'tools postinstall' and \
|
|
args[0] +' '+ args[1] != 'backup restore')):
|
|
from moulinette.interfaces.cli import get_locale
|
|
|
|
# Init i18n
|
|
m18n.load_namespace('yunohost')
|
|
m18n.set_locale(get_locale())
|
|
|
|
# Print error and exit
|
|
_die(m18n.n('yunohost_not_installed'), m18n.g('error'))
|
|
|
|
# Execute the action
|
|
from moulinette import cli
|
|
ret = cli(_retrieve_namespaces(), args,
|
|
use_cache=opts.use_cache, output_as=opts.output_as,
|
|
password=opts.password, parser_kwargs={'top_parser': parser}
|
|
)
|
|
sys.exit(ret)
|