mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
219 lines
6.6 KiB
Python
Executable file
219 lines
6.6 KiB
Python
Executable file
#! /usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
|
|
# 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')
|
|
|
|
|
|
import moulinette
|
|
from moulinette.actionsmap import ActionsMap
|
|
from moulinette.interfaces.cli import colorize, get_locale
|
|
|
|
|
|
# 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_cli_args():
|
|
"""Parse additional arguments for the cli"""
|
|
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', 'none'], 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('--timeout',
|
|
type=int, default=None,
|
|
help="Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock",
|
|
)
|
|
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"""
|
|
# 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 and 'tty' in root_handlers:
|
|
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,
|
|
},
|
|
'moulinette.interface': {
|
|
'level': level,
|
|
'handlers': handlers,
|
|
'propagate': False,
|
|
},
|
|
},
|
|
'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 = ['yunohost']
|
|
for n in ActionsMap.get_namespaces():
|
|
# Append YunoHost modules
|
|
if n.startswith('ynh_'):
|
|
ret.append(n)
|
|
return ret
|
|
|
|
|
|
# Main action ----------------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
if os.geteuid() != 0:
|
|
# since moulinette isn't initialized, we can't use m18n here
|
|
sys.stderr.write("\033[1;31mError:\033[0m yunohost command must be " \
|
|
"run as root or with sudo.\n")
|
|
sys.exit(1)
|
|
|
|
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')):
|
|
# 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
|
|
ret = moulinette.cli(
|
|
_retrieve_namespaces(), args,
|
|
use_cache=opts.use_cache, output_as=opts.output_as,
|
|
password=opts.password, parser_kwargs={'top_parser': parser},
|
|
timeout=opts.timeout,
|
|
)
|
|
sys.exit(ret)
|