diff --git a/.gitignore b/.gitignore index 19bf7c38..4492aeb8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ build eggs parts bin +cache var sdist develop-eggs @@ -22,10 +23,12 @@ pip-log.txt .coverage .tox -#Translations +# Translations *.mo -#Mr Developer +# Mr Developer .mr.developer.cfg +# Moulinette doc/*.json +src/moulinette/package.py diff --git a/bin/yunohost b/bin/yunohost index 001148a5..4c0919f7 100755 --- a/bin/yunohost +++ b/bin/yunohost @@ -35,8 +35,9 @@ if __name__ == '__main__': raise YunoHostError(17, _("YunoHost is not correctly installed, please execute 'yunohost tools postinstall'")) # Execute the action - ret = cli(['yunohost', 'test'], args, use_cache) + ret = cli(['yunohost'], args, use_cache) except YunoHostError as e: + # TODO: Remove this and associated import when yunohost package has been revisited print(colorize(_("Error: "), 'red') + e.message) sys.exit(e.code) sys.exit(ret) diff --git a/bin/yunohost-api b/bin/yunohost-api index 2baf31b4..1c1538a8 100755 --- a/bin/yunohost-api +++ b/bin/yunohost-api @@ -42,7 +42,7 @@ if __name__ == '__main__': try: # Run the server - api(['yunohost', 'test'], 6787, + api(['yunohost'], 6787, {('GET', '/installed'): is_installed}, use_cache) except MoulinetteError as e: from moulinette.interfaces.cli import colorize diff --git a/lib/yunohost/app.py b/lib/yunohost/app.py index eeb9808b..f75cae7a 100644 --- a/lib/yunohost/app.py +++ b/lib/yunohost/app.py @@ -23,6 +23,9 @@ Manage apps """ +import logging +logging.warning('the module yunohost.app has not been revisited and updated yet') + import os import sys import json diff --git a/lib/yunohost/backup.py b/lib/yunohost/backup.py index d4723d9d..390c8637 100644 --- a/lib/yunohost/backup.py +++ b/lib/yunohost/backup.py @@ -23,6 +23,9 @@ Manage backups """ +import logging +logging.warning('the module yunohost.backup has not been revisited and updated yet') + import os import sys import json diff --git a/lib/yunohost/domain.py b/lib/yunohost/domain.py index b10a92a7..ff0baaed 100644 --- a/lib/yunohost/domain.py +++ b/lib/yunohost/domain.py @@ -23,6 +23,9 @@ Manage domains """ +import logging +logging.warning('the module yunohost.backup has not been revisited and updated yet') + import os import sys import datetime diff --git a/lib/yunohost/dyndns.py b/lib/yunohost/dyndns.py index 1bd6b6ba..83a4db36 100644 --- a/lib/yunohost/dyndns.py +++ b/lib/yunohost/dyndns.py @@ -23,6 +23,9 @@ Subscribe and Update DynDNS Hosts """ +import logging +logging.warning('the module yunohost.dyndns has not been revisited and updated yet') + import os import sys import requests diff --git a/lib/yunohost/firewall.py b/lib/yunohost/firewall.py index 3fb68dea..ce011841 100644 --- a/lib/yunohost/firewall.py +++ b/lib/yunohost/firewall.py @@ -23,6 +23,9 @@ Manage firewall rules """ +import logging +logging.warning('the module yunohost.firewall has not been revisited and updated yet') + import os import sys try: diff --git a/lib/yunohost/hook.py b/lib/yunohost/hook.py index 9136acfb..7d57f733 100644 --- a/lib/yunohost/hook.py +++ b/lib/yunohost/hook.py @@ -23,6 +23,9 @@ Manage hooks """ +import logging +logging.warning('the module yunohost.hook has not been revisited and updated yet') + import os import sys import re diff --git a/lib/yunohost/monitor.py b/lib/yunohost/monitor.py index cd0a22ae..be01eadb 100644 --- a/lib/yunohost/monitor.py +++ b/lib/yunohost/monitor.py @@ -23,6 +23,9 @@ Monitoring functions """ +import logging +logging.warning('the module yunohost.monitor has not been revisited and updated yet') + import re import json import time diff --git a/lib/yunohost/service.py b/lib/yunohost/service.py index 139e1ca2..c3ce1fa9 100644 --- a/lib/yunohost/service.py +++ b/lib/yunohost/service.py @@ -23,6 +23,9 @@ Manage services """ +import logging +logging.warning('the module yunohost.service has not been revisited and updated yet') + import yaml import glob import subprocess diff --git a/lib/yunohost/tools.py b/lib/yunohost/tools.py index dd57d47f..e69dfac2 100644 --- a/lib/yunohost/tools.py +++ b/lib/yunohost/tools.py @@ -23,6 +23,9 @@ Specific tools """ +import logging +logging.warning('the module yunohost.tools has not been revisited and updated yet') + import os import sys import yaml diff --git a/lib/yunohost/user.py b/lib/yunohost/user.py index b619a227..06a09c7b 100644 --- a/lib/yunohost/user.py +++ b/lib/yunohost/user.py @@ -23,6 +23,9 @@ Manage users """ +import logging +logging.warning('the module yunohost.user has not been revisited and updated yet') + import os import sys import ldap diff --git a/yunohost b/yunohost deleted file mode 100755 index 5eebbe9b..00000000 --- a/yunohost +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os -import sys -import argparse -import gettext -import getpass -try: - import yaml -except ImportError: - sys.stderr.write('Error: Yunohost CLI Require yaml lib\n') - sys.stderr.write('apt-get install python-yaml\n') - sys.exit(1) -import json -if not __debug__: - import traceback - -gettext.install('YunoHost') - -try: - from yunohost import YunoHostError, YunoHostLDAP, str_to_func, colorize, pretty_print_dict, display_error, validate, win, parse_dict -except ImportError: - sys.stderr.write('Error: Yunohost CLI Require YunoHost lib\n') - sys.exit(1) - - -def main(): - """ - Main instructions - - Parse the action_dict and execute the action-specific function, - then print json or pretty result if executed in a tty :) - - Returns: - int -- 0 or error code - - """ - - if len(sys.argv) < 2: - sys.argv.append('-h') - - with open('action_map.yml') as f: - action_map = yaml.load(f) - - admin_password_provided = False - json_print = False - write_ldap = True - postinstall = False - - for key, arg in enumerate(sys.argv): - if arg == '--admin-password': - admin_password_provided = True - admin_password = sys.argv[key+1] - sys.argv.pop(key) - sys.argv.pop(key) - if arg == '--no-ldap': - write_ldap = False - sys.argv.pop(key) - if arg == '--json': - json_print = True - sys.argv.pop(key) - - try: - try: - with open('/etc/yunohost/installed') as f: pass - except IOError: - postinstall = True - if len(sys.argv) < 3 or sys.argv[1] != 'tools' or sys.argv[2] != 'postinstall': - raise YunoHostError(17, _("YunoHost is not correctly installed, please execute 'yunohost tools postinstall'")) - - args = parse_dict(action_map) - args_dict = vars(args).copy() - for key in args_dict.keys(): - sanitized_key = key.replace('-', '_') - if sanitized_key is not key: - args_dict[sanitized_key] = args_dict[key] - del args_dict[key] - del args_dict['func'] - try: - with open('/etc/yunohost/passwd') as f: - admin_password = f.read() - admin_password_provided = True - except IOError: pass - if postinstall: - result = args.func(**args_dict) - elif admin_password_provided: - with YunoHostLDAP(password=admin_password): - result = args.func(**args_dict) - elif os.isatty(1) and write_ldap: - admin_password = getpass.getpass(colorize(_('Admin Password: '), 'yellow')) - with YunoHostLDAP(password=admin_password): - try: - with open('/var/run/yunohost.pid', 'r'): - raise YunoHostError(1, _("A YunoHost command is already running")) - except IOError: - with open('/var/run/yunohost.pid', 'w') as f: - f.write('ldap') - os.system('chmod 400 /var/run/yunohost.pid') - with open('/etc/yunohost/passwd', 'w') as f: - f.write(admin_password) - os.system('chmod 400 /etc/yunohost/passwd') - try: - result = args.func(**args_dict) - except KeyboardInterrupt, EOFError: - raise YunoHostError(125, _("Interrupted")) - finally: - os.remove('/etc/yunohost/passwd') - os.remove('/var/run/yunohost.pid') - else: - with YunoHostLDAP(anonymous=True): - result = args.func(**args_dict) - #except TypeError, error: - #if not __debug__ : - #traceback.print_exc() - #print(_("Not (yet) implemented function")) - #return 1 - except YunoHostError, error: - display_error(error, json_print) - return error.code - else: - if json_print or not os.isatty(1) and result is not None: - if len(win) > 0: - result['success'] = win - print(json.dumps(result)) - elif result is not None: - pretty_print_dict(result) - else: - pass - - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/yunohost.tac b/yunohost.tac deleted file mode 100755 index b3d1ac61..00000000 --- a/yunohost.tac +++ /dev/null @@ -1,273 +0,0 @@ -# -*- mode: python -*- -import os -import sys -import gettext -import ldap -import yaml -import json - -sys.path.append('/usr/share/pyshared') - -from twisted.python.log import ILogObserver, FileLogObserver, startLogging, msg -from twisted.python.logfile import DailyLogFile -from twisted.web.server import Site, http -from twisted.internet import reactor -from twisted.application import internet,service -from txrestapi.resource import APIResource -from yunohost import YunoHostError, YunoHostLDAP, str_to_func, colorize, pretty_print_dict, display_error, validate, win, parse_dict -import yunohost - -if not __debug__: - import traceback - -gettext.install('YunoHost') - -dev = False -installed = True -action_dict = {} -api = APIResource() - -def http_exec(request, **kwargs): - global installed - - request.setHeader('Access-Control-Allow-Origin', '*') # Allow cross-domain requests - request.setHeader('Content-Type', 'application/json') # Return JSON anyway - - # Return OK to 'OPTIONS' xhr requests - if request.method == 'OPTIONS': - request.setResponseCode(200, 'OK') - request.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type') - request.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') - return '' - - # Simple HTTP auth - elif installed: - authorized = False - pwd = request.getPassword() - if request.getUser() == 'admin' and pwd != '': - authorized = True - if dev and 'api_key' in request.args: - pwd = request.args['api_key'][0] - authorized = True - if authorized: - try: YunoHostLDAP(password=pwd) - except YunoHostError: authorized = False - if not authorized: - request.setResponseCode(401, 'Unauthorized') - request.setHeader('Access-Control-Allow-Origin', '*') - request.setHeader('www-authenticate', 'Basic realm="Restricted Area"') - return 'Unauthorized' - - path = request.path - if request.method == 'PUT': - given_args = http.parse_qs(request.content.read(), 1) - else: - given_args = request.args - if kwargs: - for k, v in kwargs.iteritems(): - dynamic_key = path.split('/')[-1] - path = path.replace(dynamic_key, '{'+ k +'}') - given_args[k] = [v] - - #msg(given_args) - # Sanitize arguments - dict = action_dict[request.method +' '+ path] - if 'arguments' in dict: possible_args = dict['arguments'] - else: possible_args = {} - for arg, params in possible_args.items(): - sanitized_key = arg.replace('-', '_') - if sanitized_key is not arg: - possible_args[sanitized_key] = possible_args[arg] - del possible_args[arg] - arg = sanitized_key - if arg[0] == '_': - if 'nargs' not in params: - possible_args[arg]['nargs'] = '*' - if 'full' in params: - new_key = params['full'][2:] - else: - new_key = arg[2:] - new_key = new_key.replace('-', '_') - possible_args[new_key] = possible_args[arg] - del possible_args[arg] - - try: - - # Validate arguments - validated_args = {} - for key, value in given_args.items(): - if key in possible_args: - # Validate args - if 'pattern' in possible_args[key]: - validate(possible_args[key]['pattern'], value) - if 'nargs' not in possible_args[key] or ('nargs' != '*' and 'nargs' != '+'): - value = value[0] - if 'choices' in possible_args[key] and value not in possible_args[key]['choices']: - raise YunoHostError(22, _('Invalid argument') + ' ' + value) - if 'action' in possible_args[key] and possible_args[key]['action'] == 'store_true': - yes = ['true', 'True', 'yes', 'Yes'] - value = value in yes - validated_args[key] = value - - func = str_to_func(dict['function']) - if func is None: - raise YunoHostError(168, _('Function not yet implemented : ') + dict['function'].split('.')[1]) - - # Execute requested function - try: - with open('/var/run/yunohost.pid', 'r'): - raise YunoHostError(1, _("A YunoHost command is already running")) - except IOError: - if dict['function'].split('.')[1] != 'tools_postinstall': - try: - with open('/etc/yunohost/installed'): pass - except IOError: - raise YunoHostError(1, _("You must run postinstall before any other actions")) - with open('/var/run/yunohost.pid', 'w') as f: - f.write('ldap') - os.system('chmod 400 /var/run/yunohost.pid') - with open('/etc/yunohost/passwd', 'w') as f: - f.write(request.getPassword()) - os.system('chmod 400 /etc/yunohost/passwd') - try: - result = func(**validated_args) - except KeyboardInterrupt, EOFError: - raise YunoHostError(125, _("Interrupted")) - finally: - try: - os.remove('/etc/yunohost/passwd') - os.remove('/var/run/yunohost.pid') - except: pass - if result is None: - result = {} - if len(yunohost.win) > 0: - result['win'] = yunohost.win - yunohost.win = [] - - # Build response - if request.method == 'POST': - request.setResponseCode(201, 'Created') - if not installed: - installed = True - elif request.method == 'DELETE': - request.setResponseCode(204, 'No Content') - else: - request.setResponseCode(200, 'OK') - - except YunoHostError, error: - - # Set response code with function's raised code - server_errors = [1, 111, 168, 169] - client_errors = [13, 17, 22, 87, 122, 125, 167] - if error.code in client_errors: - request.setResponseCode(400, 'Bad Request') - else: - request.setResponseCode(500, 'Internal Server Error') - - result = { 'error' : error.message } - - return json.dumps(result) - -def api_doc(request): - request.setHeader('Access-Control-Allow-Origin', '*') # Allow cross-domain requests - request.setHeader('Content-Type', 'application/json') # Return JSON anyway - - # Return OK to 'OPTIONS' xhr requests - if request.method == 'OPTIONS': - request.setResponseCode(200, 'OK') - request.setHeader('Access-Control-Allow-Headers', 'Authorization') - return '' - - if request.path == '/api': - with open('doc/resources.json') as f: - return f.read() - - category = request.path.split('/')[2] - try: - with open('doc/'+ category +'.json') as f: - return f.read() - except IOError: - return '' - -def favicon(request): - request.setHeader('Access-Control-Allow-Origin', '*') # Allow cross-domain requests - request.setResponseCode(404, 'Not Found') - return '' - -def is_installed(request): - global installed - - try: - with open('/etc/yunohost/installed'): - installed = True - except IOError: - installed = False - request.setHeader('Access-Control-Allow-Origin', '*') # Allow cross-domain requests - request.setResponseCode(200, 'OK') - return json.dumps({ 'installed': installed }) - -def main(): - global action_dict - global api - global installed - - # Generate API doc - os.system('python ./generate_api_doc.py') - - # Register API doc service - api.register('ALL', '/api', api_doc) - - # favicon.ico error - api.register('ALL', '/favicon.ico', favicon) - - # Load & parse yaml file - with open('action_map.yml') as f: - action_map = yaml.load(f) - - # Register only postinstall action if YunoHost isn't completely set up - try: - with open('/etc/yunohost/installed'): - installed = True - except IOError: - installed = False - - del action_map['general_arguments'] - for category, category_params in action_map.items(): - api.register('ALL', '/api/'+ category, api_doc) - for action, action_params in category_params['actions'].items(): - if 'action_help' not in action_params: - action_params['action_help'] = '' - if 'api' not in action_params: - action_params['api'] = 'GET /'+ category +'/'+ action - method, path = action_params['api'].split(' ') - # Register route - if '{' in path: - path = path.replace('{', '(?P<').replace('}', '>[^/]+)') - api.register(method, path, http_exec) - api.register('OPTIONS', path, http_exec) - action_dict[action_params['api']] = { - 'function': 'yunohost_'+ category +'.'+ category +'_'+ action.replace('-', '_'), - 'help' : action_params['action_help'] - } - if 'arguments' in action_params: - action_dict[action_params['api']]['arguments'] = action_params['arguments'] - - api.register('ALL', '/installed', is_installed) - - - -if __name__ == '__main__': - if '--dev' in sys.argv: - dev = True - startLogging(sys.stdout) - else: - startLogging(open('/var/log/yunohost.log', 'a+')) # Log actions to file - main() - reactor.listenTCP(6787, Site(api, timeout=None)) - reactor.run() -else: - application = service.Application("YunoHost API") - logfile = DailyLogFile("yunohost.log", "/var/log") - application.setComponent(ILogObserver, FileLogObserver(logfile).emit) - main() - internet.TCPServer(6787, Site(api, timeout=None)).setServiceParent(application)