2013-10-18 14:46:30 +02:00
|
|
|
# -*- 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
|
2014-02-05 02:01:03 +01:00
|
|
|
|
2014-02-24 19:11:09 +01:00
|
|
|
from moulinette.core.helpers import YunoHostError, YunoHostLDAP, win_msg, colorize
|
2013-10-18 14:46:30 +02:00
|
|
|
|
2013-12-09 19:37:16 +01:00
|
|
|
hook_folder = '/usr/share/yunohost/hooks/'
|
2013-10-18 14:46:30 +02:00
|
|
|
|
2013-12-10 00:47:30 +01:00
|
|
|
def hook_add(app, file):
|
2013-10-18 14:46:30 +02:00
|
|
|
"""
|
2013-10-31 11:21:59 +01:00
|
|
|
Store hook script to filsystem
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
Keyword argument:
|
2013-12-10 00:47:30 +01:00
|
|
|
app -- App to link with
|
|
|
|
file -- Script to add (/path/priority-file)
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
"""
|
2013-12-10 00:47:30 +01:00
|
|
|
path, filename = os.path.split(file)
|
|
|
|
if '-' in filename:
|
|
|
|
priority, action = filename.split('-')
|
|
|
|
else:
|
|
|
|
priority = '50'
|
|
|
|
action = filename
|
|
|
|
|
2013-10-18 14:46:30 +02:00
|
|
|
try: os.listdir(hook_folder + action)
|
|
|
|
except OSError: os.makedirs(hook_folder + action)
|
2013-11-22 15:29:07 +01:00
|
|
|
|
2013-12-10 00:47:30 +01:00
|
|
|
finalpath = hook_folder + action +'/'+ priority +'-'+ app
|
|
|
|
print app
|
|
|
|
os.system('cp '+ file +' '+ finalpath)
|
|
|
|
os.system('chown -hR admin: '+ hook_folder)
|
|
|
|
|
|
|
|
return { 'hook': finalpath }
|
|
|
|
|
|
|
|
|
|
|
|
def hook_remove(app):
|
|
|
|
"""
|
|
|
|
Remove hooks linked to a specific app
|
|
|
|
|
|
|
|
Keyword argument:
|
|
|
|
app -- Scripts related to app will be removed
|
2013-12-09 19:44:10 +01:00
|
|
|
|
2013-12-10 00:47:30 +01:00
|
|
|
"""
|
2013-12-19 13:50:32 +01:00
|
|
|
try:
|
|
|
|
for action in os.listdir(hook_folder):
|
|
|
|
for script in os.listdir(hook_folder + action):
|
|
|
|
if script.endswith(app):
|
|
|
|
os.remove(hook_folder + action +'/'+ script)
|
|
|
|
except OSError: pass
|
2013-11-22 15:29:07 +01:00
|
|
|
|
2013-10-18 14:46:30 +02:00
|
|
|
|
2013-12-09 19:37:16 +01:00
|
|
|
def hook_callback(action, args=None):
|
2013-10-18 14:46:30 +02:00
|
|
|
"""
|
|
|
|
Execute all scripts binded to an action
|
|
|
|
|
|
|
|
Keyword argument:
|
|
|
|
action -- Action name
|
2013-12-09 19:37:16 +01:00
|
|
|
args -- Ordered list of arguments to pass to the script
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
"""
|
2013-10-18 15:48:01 +02:00
|
|
|
with YunoHostLDAP() as yldap:
|
|
|
|
try: os.listdir(hook_folder + action)
|
2013-12-09 19:37:16 +01:00
|
|
|
except OSError: pass
|
|
|
|
else:
|
|
|
|
if args is None:
|
|
|
|
args = []
|
|
|
|
elif not isinstance(args, list):
|
|
|
|
args = [args]
|
2013-10-18 14:46:30 +02:00
|
|
|
|
2013-12-09 19:37:16 +01:00
|
|
|
for hook in os.listdir(hook_folder + action):
|
|
|
|
try:
|
|
|
|
hook_exec(file=hook_folder + action +'/'+ hook, args=args)
|
|
|
|
except: pass
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
def hook_check(file):
|
|
|
|
"""
|
|
|
|
Parse the script file and get arguments
|
|
|
|
|
|
|
|
Keyword argument:
|
2013-10-28 18:17:13 +01:00
|
|
|
file -- File to check
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
"""
|
2013-10-28 18:17:13 +01:00
|
|
|
try:
|
2013-10-29 16:12:01 +01:00
|
|
|
with open(file[:file.index('scripts/')] + 'manifest.json') as f:
|
2013-10-28 18:17:13 +01:00
|
|
|
manifest = json.loads(str(f.read()))
|
|
|
|
except:
|
|
|
|
raise YunoHostError(22, _("Invalid app package"))
|
|
|
|
|
|
|
|
action = file[file.index('scripts/') + 8:]
|
2013-12-25 15:16:24 +01:00
|
|
|
if 'arguments' in manifest and action in manifest['arguments']:
|
|
|
|
return manifest['arguments'][action]
|
2013-10-18 14:46:30 +02:00
|
|
|
else:
|
2013-10-28 18:17:13 +01:00
|
|
|
return {}
|
|
|
|
|
2013-10-18 14:46:30 +02:00
|
|
|
|
|
|
|
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:
|
2013-12-09 19:37:16 +01:00
|
|
|
if isinstance(args, list):
|
|
|
|
arg_list = args
|
|
|
|
else:
|
|
|
|
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']:
|
|
|
|
raise YunoHostError(22, _("Invalid choice") + ': ' + args[arg['name']])
|
|
|
|
arg_list.append(args[arg['name']])
|
2013-10-18 14:46:30 +02:00
|
|
|
else:
|
2013-12-09 19:37:16 +01:00
|
|
|
if os.isatty(1) and 'ask' in arg:
|
|
|
|
ask_string = arg['ask']['en'] #TODO: I18n
|
|
|
|
if 'choices' in arg:
|
|
|
|
ask_string = ask_string +' ('+ '|'.join(arg['choices']) +')'
|
|
|
|
if 'default' in arg:
|
|
|
|
ask_string = ask_string +' (default: '+ arg['default'] +')'
|
|
|
|
|
|
|
|
input_string = raw_input(colorize(ask_string + ': ', 'cyan'))
|
|
|
|
|
|
|
|
if input_string == '' and 'default' in arg:
|
|
|
|
input_string = arg['default']
|
|
|
|
|
|
|
|
arg_list.append(input_string)
|
|
|
|
elif 'default' in arg:
|
|
|
|
arg_list.append(arg['default'])
|
|
|
|
else:
|
|
|
|
raise YunoHostError(22, _("Missing arguments") + ': ' + arg['name'])
|
2013-10-18 14:46:30 +02:00
|
|
|
|
2013-10-25 12:11:24 +02:00
|
|
|
file_path = "./"
|
|
|
|
if "/" in file and file[0:2] != file_path:
|
|
|
|
file_path = os.path.dirname(file)
|
|
|
|
file = file.replace(file_path +"/", "")
|
|
|
|
return os.system('su - admin -c "cd \\"'+ file_path +'\\" && bash \\"'+ file +'\\" '+ ' '.join(arg_list) +'"') #TODO: Allow python script
|