Warn about non-reviewed yunohost package and clean up

This commit is contained in:
Jerome Lebleu 2014-03-25 18:56:51 +01:00
parent b3af4ddaea
commit fa0a7affdd
15 changed files with 38 additions and 411 deletions

3
.gitignore vendored
View file

@ -10,6 +10,7 @@ build
eggs
parts
bin
cache
var
sdist
develop-eggs
@ -28,4 +29,6 @@ pip-log.txt
# Mr Developer
.mr.developer.cfg
# Moulinette
doc/*.json
src/moulinette/package.py

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

134
yunohost
View file

@ -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())

View file

@ -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)