From b0f1bea9a14375e421a38b01d8e8d3e8508671e2 Mon Sep 17 00:00:00 2001 From: kload Date: Fri, 18 Oct 2013 12:46:30 +0000 Subject: [PATCH] Add hook management --- action_map.yml | 50 +++++++++++++++++-- yunohost.py | 2 +- yunohost_domain.py | 7 +-- yunohost_hook.py | 119 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 yunohost_hook.py diff --git a/action_map.yml b/action_map.yml index 15f8844c..907540e6 100644 --- a/action_map.yml +++ b/action_map.yml @@ -204,11 +204,7 @@ domain: ssowatconf: action_help: Regenerate SSOwat configuration file api: PUT /ssowatconf - arguments: - -r: - full: --returns - help: Return boolean - action: store_true + ############################# # App # @@ -643,3 +639,47 @@ tools: help: Subscribe domain to a DynDNS service action: store_true + +############################# +# Hook # +############################# +hook: + category_help: Manage hooks + actions: + + ### hook_add() + add: + action_help: Store hook script to filsystem + api: PUT /hook + arguments: + action: + help: Action folder to store into + file: + help: Script to check + + ### hook_callback() + callback: + action_help: Execute all scripts binded to an action + api: GET /hooks + arguments: + action: + help: Action name + + ### hook_check() + check: + action_help: Parse the script file and get arguments + api: GET /hook/check + arguments: + file: + help: Script to check + + ### hook_exec() + exec: + action_help: Execute hook from a file with arguments + api: GET /hook + arguments: + file: + help: Script to execute + -a: + full: --args + help: Arguments to pass to the script diff --git a/yunohost.py b/yunohost.py index 052ec1b9..77cde39e 100644 --- a/yunohost.py +++ b/yunohost.py @@ -179,7 +179,7 @@ def get_required_args(args, required_args, password=False): if os.isatty(1): args[arg] = raw_input(colorize(phrase + ': ', 'cyan')) else: - raise Exception #FIX + raise Exception #TODO: fix # Password if 'password' in required_args and password: if not args['password']: diff --git a/yunohost_domain.py b/yunohost_domain.py index 88aacc6d..4fc20a46 100644 --- a/yunohost_domain.py +++ b/yunohost_domain.py @@ -252,12 +252,12 @@ def domain_remove(domains): return { 'Domains' : result } -def domain_ssowatconf(returns=False): +def domain_ssowatconf(): """ Regenerate SSOwat conf from YunoHost settings Keyword argument: - Returns + """ with open('/etc/yunohost/current_host', 'r') as f: @@ -285,6 +285,3 @@ def domain_ssowatconf(returns=False): json.dump(conf_dict, f) win_msg(_('SSOwat configuration generated')) - - if returns: - return True diff --git a/yunohost_hook.py b/yunohost_hook.py new file mode 100644 index 00000000..f73aaec4 --- /dev/null +++ b/yunohost_hook.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- + +""" License + + Copyright (C) 2013 YunoHost + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, see http://www.gnu.org/licenses + +""" + +""" yunohost_hook.py + + Manage hooks +""" +import os +import sys +import re +import json +from yunohost import YunoHostError, YunoHostLDAP, win_msg, colorize + +hook_folder = '/user/share/yunohost/hooks/' + +def hook_add(action, file): + """ + Store hook script to fs + + Keyword argument: + action -- Action folder to store into + file -- Script file to store + + """ + try: os.listdir(hook_folder + action) + except OSError: os.makedirs(hook_folder + action) + + os.system('cp '+ file +' '+ hook_folder + action) + + +def hook_callback(action): + """ + Execute all scripts binded to an action + + Keyword argument: + action -- Action name + + """ + try: os.listdir(hook_folder + action) + except OSError: os.makedirs(hook_folder + action) + + for hook in os.listdir(hook_folder + action): + hook_exec(file=hook_folder + action +'/'+ hook) + + +def hook_check(file): + """ + Parse the script file and get arguments + + Keyword argument: + file -- Script to check + + """ + + with open(file, 'r') as conf: + script_lines = conf.readlines() + + in_block = False + json_string = "" + for line in script_lines: + if re.search(r'^#### json"', line): + in_block = True + if in_block and re.search(r'^####', line): + in_block = False + elif re.search(r'^##[^#;]', line): + json_string = json_string + line[2:] + + if json_string == "": + return {} + else: + return json.loads(json_string)['arguments'] + +def hook_exec(file, args=None): + """ + Execute hook from a file with arguments + + Keyword argument: + file -- Script to execute + args -- Arguments to pass to the script + + """ + with YunoHostLDAP() as yldap: + required_args = hook_check(file) + if args is None: + args = {} + + arg_list = [] + for arg in required_args: + if arg['name'] in args: + if 'choices' in arg and args[arg['name']] not in arg['choices'].split('|'): + raise YunoHostError(22, _("Invalid choice") + ': ' + args[arg['name']]) + arg_list.append(args[arg['name']]) + else: + if 'default' in arg: + arg_list.append(arg['default']) + elif os.isatty(1) and 'ask' in arg: + arg_list.append(raw_input(colorize(arg['ask']['en'] + ': ', 'cyan'))) #TODO: I18n + else: + raise YunoHostError(22, _("Missing arguments") + ': ' + arg_name) + + os.system('su - admin -c "bash \\"'+ file +'\\" '+ ' '.join(arg_list) +'"')