From eb45d39e8910cbd467e3f3239f9d47ad5fa14110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Mon, 29 Dec 2014 18:39:36 +0100 Subject: [PATCH 01/10] [fix] NonBlockingStreamReader is now in utils.stream --- hook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hook.py b/hook.py index 4c7595de2..ccfd242b8 100644 --- a/hook.py +++ b/hook.py @@ -252,7 +252,7 @@ def hook_exec(file, args=None): args -- Arguments to pass to the script """ - from moulinette.helpers import NonBlockingStreamReader + from moulinette.utils.stream import NonBlockingStreamReader from yunohost.app import _value_for_locale if isinstance(args, list): From 1c96b4f9a3d15f3ffbaa509fa9ade75f5ba4030b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Tue, 30 Dec 2014 01:18:32 +0100 Subject: [PATCH 02/10] [enh] Refactor firewall_upnp action * make sure to save final UPnP status (fix #42) * deprecate the 'reload' action and replace it with a new 'status' action which retrieve current UPnP status * allow to not refresh port forwarding with the --no-refresh argument * some other small changes, e.g. set the action argument to one optionnal choice, rename the UPnP cron job file, add logging --- actionsmap/yunohost.yml | 11 ++- firewall.py | 157 +++++++++++++++++++++++++--------------- locales/en.json | 9 ++- locales/fr.json | 9 ++- tools.py | 9 +-- 5 files changed, 120 insertions(+), 75 deletions(-) diff --git a/actionsmap/yunohost.yml b/actionsmap/yunohost.yml index d73157433..60d29a85c 100644 --- a/actionsmap/yunohost.yml +++ b/actionsmap/yunohost.yml @@ -934,17 +934,20 @@ firewall: ### firewall_upnp() upnp: - action_help: Add uPnP cron and enable uPnP in firewall.yml, or the opposite. + action_help: Manage port forwarding using UPnP api: GET /firewall/upnp arguments: action: - help: enable/disable choices: - enable - disable + - status - reload - - [] - nargs: "*" + nargs: "?" + default: status + --no-refresh: + help: Do not refresh port forwarding + action: store_true ### firewall_stop() stop: diff --git a/firewall.py b/firewall.py index 08b63b3bc..4b4e3a35e 100644 --- a/firewall.py +++ b/firewall.py @@ -34,6 +34,7 @@ except ImportError: sys.exit(1) from moulinette.core import MoulinetteError +from moulinette.utils.log import getActionLogger """ Search the ssh port in ssh config file If we don't find the ssh port we define 22""" @@ -56,6 +57,11 @@ except: ssh_port = '22' ssh_port = int(ssh_port) +firewall_file = '/etc/yunohost/firewall.yml' +upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp' + +logger = getActionLogger('yunohost.firewall') + def firewall_allow(port=None, protocol=['TCP'], ipv6=False, no_upnp=False): """ @@ -94,7 +100,7 @@ def firewall_allow(port=None, protocol=['TCP'], ipv6=False, no_upnp=False): else: msignals.display(m18n.n('port_already_opened', port), 'warning') - with open('/etc/yunohost/firewall.yml', 'w') as f: + with open(firewall_file, 'w') as f: yaml.safe_dump(firewall, f, default_flow_style=False) return firewall_reload() @@ -134,7 +140,7 @@ def firewall_disallow(port=None, protocol=['TCP'], ipv6=False): else: msignals.display(m18n.n('port_already_closed', port), 'warning') - with open('/etc/yunohost/firewall.yml', 'w') as f: + with open(firewall_file, 'w') as f: yaml.safe_dump(firewall, f, default_flow_style=False) return firewall_reload() @@ -148,7 +154,7 @@ def firewall_list(raw=False): raw -- Return the complete YAML dict """ - with open('/etc/yunohost/firewall.yml') as f: + with open(firewall_file) as f: firewall = yaml.load(f) if raw: @@ -172,7 +178,7 @@ def firewall_reload(): if os.system("iptables -P INPUT ACCEPT") != 0: raise MoulinetteError(errno.ESRCH, m18n.n('iptables_unavailable')) if upnp: - firewall_upnp(action=['reload']) + firewall_upnp(no_refresh=False) os.system("iptables -F") os.system("iptables -X") @@ -218,75 +224,112 @@ def firewall_reload(): return firewall_list() -def firewall_upnp(action=None): +def firewall_upnp(action='status', no_refresh=False): """ - Add uPnP cron and enable uPnP in firewall.yml, or the opposite. + Manage port forwarding using UPnP + + Note: 'reload' action is deprecated and will be removed in the near + future. You should use 'status' instead - which retrieve UPnP status + and automatically refresh port forwarding if 'no_refresh' is False. Keyword argument: - action -- enable/disable/reload + action -- Action to perform + no_refresh -- Do not refresh port forwarding """ firewall = firewall_list(raw=True) + enabled = firewall['uPnP']['enabled'] - if action: - action = action[0] - - if action == 'enable': - firewall['uPnP']['enabled'] = True - - with open('/etc/cron.d/yunohost-firewall', 'w+') as f: - f.write('PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ - \n*/50 * * * * root yunohost firewall upnp reload >>/dev/null') - - msignals.display(m18n.n('upnp_enabled'), 'success') - - if action == 'disable': - firewall['uPnP']['enabled'] = False - + # Compatibility with previous version + if action == 'reload': + logger.warning("'reload' action is deprecated and will be removed") try: - upnpc = miniupnpc.UPnP() - upnpc.discoverdelay = 3000 - if upnpc.discover() == 1: + # Remove old cron job + os.remove('/etc/cron.d/yunohost-firewall') + except: pass + action = 'status' + no_refresh = False + + if action == 'status' and no_refresh: + # Only return current state + return { 'enabled': enabled } + elif action == 'enable' or (enabled and action == 'status'): + # Add cron job + with open(upnp_cron_job, 'w+') as f: + f.write('*/50 * * * * root ' + '/usr/bin/yunohost firewall upnp status >>/dev/null\n') + enabled = True + elif action == 'disable' or (not enabled and action == 'status'): + try: + # Remove cron job + os.remove(upnp_cron_job) + except: pass + enabled = False + if action == 'status': + no_refresh = True + else: + raise MoulinetteError(errno.EINVAL, m18n.n('action_invalid', action)) + + # Refresh port mapping using UPnP + if not no_refresh: + upnpc = miniupnpc.UPnP() + upnpc.discoverdelay = 3000 + + # Discover UPnP device(s) + logger.debug('discovering UPnP devices...') + nb_dev = upnpc.discover() + logger.debug('found %d UPnP device(s)', int(nb_dev)) + if nb_dev < 1: + msignals.display(m18n.n('upnp_dev_not_found'), 'error') + enabled = False + else: + try: + # Select UPnP device upnpc.selectigd() + except: + logger.exception('unable to select UPnP device') + enabled = False + else: + # Iterate over ports for protocol in ['TCP', 'UDP']: for port in firewall['uPnP'][protocol]: + # Clean the mapping of this port if upnpc.getspecificportmapping(port, protocol): - try: upnpc.deleteportmapping(port, protocol) + try: + upnpc.deleteportmapping(port, protocol) except: pass - except: pass + if not enabled: + continue + try: + # Add new port mapping + upnpc.addportmapping(port, protocol, upnpc.lanaddr, + port, 'yunohost firewall: port %d' % port, '') + except: + logger.exception('unable to add port %d using UPnP', + port) + enabled = False + if enabled != firewall['uPnP']['enabled']: + firewall['uPnP']['enabled'] = enabled - try: os.remove('/etc/cron.d/yunohost-firewall') - except: pass - - msignals.display(m18n.n('upnp_disabled'), 'success') - - if action == 'reload': - upnp = firewall['uPnP']['enabled'] - - if upnp: - try: - upnpc = miniupnpc.UPnP() - upnpc.discoverdelay = 3000 - if upnpc.discover() == 1: - upnpc.selectigd() - for protocol in ['TCP', 'UDP']: - for port in firewall['uPnP'][protocol]: - if upnpc.getspecificportmapping(port, protocol): - try: upnpc.deleteportmapping(port, protocol) - except: pass - upnpc.addportmapping(port, protocol, upnpc.lanaddr, port, 'yunohost firewall : port %d' % port, '') - else: - raise MoulinetteError(errno.ENXIO, m18n.n('upnp_dev_not_found')) - except: - msignals.display(m18n.n('upnp_port_open_failed'), 'warning') - - if action: - os.system("cp /etc/yunohost/firewall.yml /etc/yunohost/firewall.yml.old") - with open('/etc/yunohost/firewall.yml', 'w') as f: + # Make a backup and update firewall file + os.system("cp {0} {0}.old".format(firewall_file)) + with open(firewall_file, 'w') as f: yaml.safe_dump(firewall, f, default_flow_style=False) - return { "enabled": firewall['uPnP']['enabled'] } + if not no_refresh: + # Display success message if needed + if action == 'enable' and enabled: + msignals.display(m18n.n('upnp_enabled'), 'success') + elif action == 'disable' and not enabled: + msignals.display(m18n.n('upnp_disabled'), 'success') + # Make sure to disable UPnP + elif action != 'disable' and not enabled: + firewall_upnp('disable', no_refresh=True) + + if action == 'enable' and not enabled: + raise MoulinetteError(errno.ENXIO, m18n.n('upnp_port_open_failed')) + return { 'enabled': enabled } def firewall_stop(): @@ -307,5 +350,5 @@ def firewall_stop(): os.system("ip6tables -F") os.system("ip6tables -X") - if os.path.exists("/etc/cron.d/yunohost-firewall"): + if os.path.exists(upnp_cron_job): firewall_upnp('disable') diff --git a/locales/en.json b/locales/en.json index ae3229f3f..121f5a0a4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -6,6 +6,7 @@ "installation_complete" : "Installation complete", "installation_failed" : "Installation failed", "unexpected_error" : "An unexpected error occured", + "action_invalid" : "Invalid action '{:s}'", "license_undefined" : "undefined", "no_appslist_found" : "No apps list found", @@ -72,10 +73,10 @@ "port_already_opened" : "Port {:d} is already opened", "port_already_closed" : "Port {:d} is already closed", "iptables_unavailable" : "You cannot play with iptables here. You are either in a container or your kernel does not support it.", - "upnp_dev_not_found" : "No uPnP device found", - "upnp_port_open_failed" : "Unable to open uPnP ports", - "upnp_enabled" : "uPnP successfully enabled", - "upnp_disabled" : "uPnP successfully disabled", + "upnp_dev_not_found" : "No UPnP device found", + "upnp_port_open_failed" : "Unable to open UPnP ports", + "upnp_enabled" : "UPnP successfully enabled", + "upnp_disabled" : "UPnP successfully disabled", "firewall_reloaded" : "Firewall successfully reloaded", "hook_list_by_invalid" : "Invalid property to list hook by", diff --git a/locales/fr.json b/locales/fr.json index 827ff34d1..268c902d0 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -6,6 +6,7 @@ "installation_complete" : "Installation terminée", "installation_failed" : "Échec de l'installation", "unexpected_error" : "Une erreur inattendue est survenue", + "action_invalid" : "Action '{:s}' incorrecte", "license_undefined" : "indéfinie", "no_appslist_found" : "Aucune liste d'applications trouvée", @@ -72,10 +73,10 @@ "port_already_opened" : "Le port {:d} est déjà ouvert", "port_already_closed" : "Le port {:d} est déjà fermé", "iptables_unavailable" : "Vous ne pouvez pas faire joujou avec iptables ici. Vous êtes sûrement dans un conteneur, autrement votre noyau ne le supporte pas.", - "upnp_dev_not_found" : "Aucun périphérique compatible uPnP trouvé", - "upnp_port_open_failed" : "Impossible d'ouvrir les ports avec uPnP", - "upnp_enabled" : "uPnP activé avec succès", - "upnp_disabled" : "uPnP désactivé avec succès", + "upnp_dev_not_found" : "Aucun périphérique compatible UPnP trouvé", + "upnp_port_open_failed" : "Impossible d'ouvrir les ports avec UPnP", + "upnp_enabled" : "UPnP activé avec succès", + "upnp_disabled" : "UPnP désactivé avec succès", "firewall_reloaded" : "Pare-feu rechargé avec succès", "hook_list_by_invalid" : "Propriété pour lister les scripts incorrecte", diff --git a/tools.py b/tools.py index 1e4fce2f4..173a4fee0 100644 --- a/tools.py +++ b/tools.py @@ -318,12 +318,9 @@ def tools_postinstall(domain, password, ignore_dyndns=False): # Change LDAP admin password tools_adminpw(old_password='yunohost', new_password=password) - # Enable uPnP - firewall_upnp(action=['enable']) - try: - firewall_reload() - except MoulinetteError: - firewall_upnp(action=['disable']) + # Enable UPnP silently and reload firewall + firewall_upnp('enable', no_refresh=True) + firewall_reload() # Enable iptables at boot time os.system('update-rc.d yunohost-firewall defaults') From 70da9abedfe9ad068686f98952328c1e102c7c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Sun, 4 Jan 2015 14:28:50 +0100 Subject: [PATCH 03/10] [enh] Use searchf helper to retrieve SSH port in firewall module --- firewall.py | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/firewall.py b/firewall.py index 4b4e3a35e..14e4bbd37 100644 --- a/firewall.py +++ b/firewall.py @@ -36,27 +36,6 @@ except ImportError: from moulinette.core import MoulinetteError from moulinette.utils.log import getActionLogger -""" Search the ssh port in ssh config file - If we don't find the ssh port we define 22""" - -try: - with open('/etc/ssh/sshd_config') as ssh_config_file: - for line in ssh_config_file: - line0 = line.split(" ")[0] - - if line0 == 'Port': - ssh_port = line.split(' ')[1] - ssh_port = ssh_port.rstrip('\n\r') - - ssh_config_file.close() - - if ssh_port == '': - ssh_port = '22' - -except: - ssh_port = '22' - -ssh_port = int(ssh_port) firewall_file = '/etc/yunohost/firewall.yml' upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp' @@ -173,6 +152,7 @@ def firewall_reload(): firewall = firewall_list(raw=True) upnp = firewall['uPnP']['enabled'] + ssh_port = _get_ssh_port() # IPv4 if os.system("iptables -P INPUT ACCEPT") != 0: @@ -352,3 +332,20 @@ def firewall_stop(): if os.path.exists(upnp_cron_job): firewall_upnp('disable') + + +def _get_ssh_port(default=22): + """Return the SSH port to use + + Retrieve the SSH port from the sshd_config file or used the default + one if it's not defined. + """ + from moulinette.utils.text import searchf + try: + m = searchf(r'^Port[ \t]+([0-9]+)$', + '/etc/ssh/sshd_config', count=-1) + if m: + return int(m) + except: + pass + return default From 22675664f0fad747797ce75e1f786a07573e7589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Tue, 6 Jan 2015 15:42:16 +0100 Subject: [PATCH 04/10] [enh] Use node anchors for patterns in the actionsmap --- actionsmap/yunohost.yml | 140 +++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 81 deletions(-) diff --git a/actionsmap/yunohost.yml b/actionsmap/yunohost.yml index 60d29a85c..6146a7dff 100644 --- a/actionsmap/yunohost.yml +++ b/actionsmap/yunohost.yml @@ -98,43 +98,43 @@ user: username: help: The unique username to create extra: - pattern: - - '^[a-z0-9_]+$' - - pattern_username + pattern: &pattern_username + - !!str ^[a-z0-9_]+$ + - "pattern_username" -f: full: --firstname extra: ask: ask_firstname required: True - pattern: - - "^([^\\W\\d_]{2,30}[ ,.'-]{0,3})+$" - - pattern_firstname + pattern: &pattern_firstname + - !!str ^([^\W\d_]{2,30}[ ,.'-]{0,3})+$ + - "pattern_firstname" -l: full: --lastname extra: ask: ask_lastname required: True - pattern: - - "^([^\\W\\d_]{2,30}[ ,.']{0,3})+$" - - pattern_lastname + pattern: &pattern_lastname + - !!str ^([^\W\d_]{2,30}[ ,.']{0,3})+$ + - "pattern_lastname" -m: full: --mail help: Main unique email address extra: ask: ask_email required: True - pattern: - - '^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$' - - pattern_email + pattern: &pattern_email + - !!str ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$ + - "pattern_email" -p: full: --password help: User password extra: password: ask_password required: True - pattern: - - '^.{3,}$' - - pattern_password + pattern: &pattern_password + - !!str ^.{3,}$ + - "pattern_password" ### user_delete() delete: @@ -146,9 +146,7 @@ user: username: help: Username to delete extra: - pattern: - - '^[a-z0-9_]+$' - - pattern_username + pattern: *pattern_username --purge: action: store_true @@ -164,33 +162,27 @@ user: -f: full: --firstname extra: - pattern: - - "^([^\\W\\d_]{2,30}[ ,.']{0,3})+$" - - pattern_firstname + pattern: *pattern_firstname -l: full: --lastname extra: - pattern: - - "^([^\\W\\d_]{2,30}[ ,.']{0,3})+$" - - pattern_lastname + pattern: *pattern_lastname -m: full: --mail extra: - pattern: - - '^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$' - - pattern_email + pattern: *pattern_email -p: full: --change-password help: New password to set metavar: PASSWORD extra: - pattern: - - '^.{3,}$' - - pattern_password + pattern: *pattern_password --add-mailforward: help: Mailforward addresses to add nargs: "*" metavar: MAIL + extra: + pattern: *pattern_email --remove-mailforward: help: Mailforward addresses to remove nargs: "*" @@ -199,6 +191,8 @@ user: help: Mail aliases to add nargs: "*" metavar: MAIL + extra: + pattern: *pattern_email --remove-mailalias: help: Mail aliases to remove nargs: "*" @@ -253,9 +247,9 @@ domain: domain: help: Domain name to add extra: - pattern: - - '^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+[a-z]{2,}$' - - pattern_domain + pattern: &pattern_domain + - !!str ^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+[a-z]{2,}$ + - "pattern_domain" -d: full: --dyndns help: Subscribe to the DynDNS service @@ -271,9 +265,7 @@ domain: domain: help: Domain to delete extra: - pattern: - - '^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+[a-z]{2,}$' - - pattern_domain + pattern: *pattern_domain ### domain_info() # info: @@ -307,9 +299,9 @@ app: full: --name help: Name of the list (default fapp) extra: - pattern: - - '^[a-z0-9_]+$' - - pattern_listname + pattern: &pattern_listname + - !!str ^[a-z0-9_]+$ + - "pattern_listname" ### app_listlists() listlists: @@ -325,9 +317,7 @@ app: help: Name of the list to remove extra: ask: ask_list_to_remove - pattern: - - '^[a-z0-9_]+$' - - pattern_listname + pattern: *pattern_listname ### app_list() list: @@ -376,9 +366,7 @@ app: full: --user help: Allowed app map for a user extra: - pattern: - - '^[a-z0-9_]+$' - - pattern_username + pattern: *pattern_username ### app_install() install: @@ -454,9 +442,9 @@ app: port: help: Port to check extra: - pattern: - - '^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$' - - pattern_port + pattern: &pattern_port + - !!str ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$ + - "pattern_port" ### app_checkurl() checkurl: @@ -568,9 +556,9 @@ backup: full: --name help: Name of the backup archive extra: - pattern: - - '^[\w\-\.]{1,30}(? Date: Sun, 11 Jan 2015 16:29:01 +0100 Subject: [PATCH 05/10] [enh] Review and add features to firewall category * allow/disallow a port for each IP version and add ipv4 and ipv6 only arguments * permit to allow/disable a range of ports * return combined IPv4 and IPv6 - TCP and UDP - ports in firewall_list and allow to sort results * review firewall_reload with new moulinette utils and log output of failed commands * add --no-reload argument to prevent firewall reloading in firewall_allow/disallow * some other small changes, e.g. add logging --- actionsmap/yunohost.yml | 66 ++++++--- firewall.py | 299 ++++++++++++++++++++++++++-------------- locales/en.json | 12 +- locales/fr.json | 12 +- 4 files changed, 261 insertions(+), 128 deletions(-) diff --git a/actionsmap/yunohost.yml b/actionsmap/yunohost.yml index 6146a7dff..ca5ce6d3a 100644 --- a/actionsmap/yunohost.yml +++ b/actionsmap/yunohost.yml @@ -864,6 +864,14 @@ firewall: full: --raw help: Return the complete YAML dict action: store_true + -i: + full: --by-ip-version + help: List rules by IP version + action: store_true + -f: + full: --list-forwarded + help: List forwarded ports with UPnP + action: store_true ### firewall_reload() reload: @@ -872,47 +880,69 @@ firewall: ### firewall_allow() allow: - action_help: Allow connection port/protocol + action_help: Allow connections on a port api: POST /firewall/port arguments: port: - help: Port to open + help: Port or range of ports to open extra: - pattern: *pattern_port - protocol: - help: Protocol associated with port + pattern: &pattern_port_or_range + - !!str ((^|(?!\A):)([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){1,2}?$ + - "pattern_port_or_range" + -p: + full: --protocol + help: "Protocol type to allow (default: TCP)" choices: - - UDP - TCP + - UDP - Both - - [] - nargs: "*" default: TCP - --ipv6: + -4: + full: --ipv4-only + help: Only add a rule for IPv4 connections + action: store_true + -6: + full: --ipv6-only + help: Only add a rule for IPv6 connections action: store_true --no-upnp: + help: Do not add forwarding of this port with UPnP + action: store_true + --no-reload: + help: Do not reload firewall rules action: store_true ### firewall_disallow() disallow: - action_help: Disallow connection + action_help: Disallow connections on a port api: DELETE /firewall/port arguments: port: - help: Port to close + help: Port or range of ports to close extra: - pattern: *pattern_port - protocol: - help: Protocol associated with port + pattern: *pattern_port_or_range + -p: + full: --protocol + help: "Protocol type to allow (default: TCP)" choices: - - UDP - TCP + - UDP - Both - - [] - nargs: "*" default: TCP - --ipv6: + -4: + full: --ipv4-only + help: Only remove the rule for IPv4 connections + action: store_true + -6: + full: --ipv6-only + help: Only remove the rule for IPv6 connections + action: store_true + --upnp-only: + help: Only remove forwarding of this port with UPnP + action: store_true + --no-reload: + help: Do not reload firewall rules action: store_true diff --git a/firewall.py b/firewall.py index 14e4bbd37..7e114f4a1 100644 --- a/firewall.py +++ b/firewall.py @@ -34,7 +34,9 @@ except ImportError: sys.exit(1) from moulinette.core import MoulinetteError +from moulinette.utils import process from moulinette.utils.log import getActionLogger +from moulinette.utils.text import prependlines firewall_file = '/etc/yunohost/firewall.yml' upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp' @@ -42,104 +44,148 @@ upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp' logger = getActionLogger('yunohost.firewall') -def firewall_allow(port=None, protocol=['TCP'], ipv6=False, no_upnp=False): +def firewall_allow(port, protocol='TCP', ipv4_only=False, ipv6_only=False, + no_upnp=False, no_reload=False): """ - Allow connection port/protocol + Allow connections on a port - Keyword argument: - port -- Port to open - protocol -- Protocol associated with port - ipv6 -- ipv6 - no_upnp -- Do not request for uPnP + Keyword arguments: + port -- Port or range of ports to open + protocol -- Protocol type to allow (default: TCP) + ipv4_only -- Only add a rule for IPv4 connections + ipv6_only -- Only add a rule for IPv6 connections + no_upnp -- Do not add forwarding of this port with UPnP + no_reload -- Do not reload firewall rules """ - port = int(port) - ipv = "ipv4" - if isinstance(protocol, list): - protocols = protocol - else: - protocols = [protocol] - protocol = protocols[0] - firewall = firewall_list(raw=True) - upnp = not no_upnp and firewall['uPnP']['enabled'] + # Validate port + if not isinstance(port, int) and ':' not in port: + port = int(port) - if ipv6: - ipv = "ipv6" + # Validate protocols + protocols = ['TCP', 'UDP'] + if protocol != 'Both' and protocol in protocols: + protocols = [protocol,] - if protocol == "Both": - protocols = ['UDP', 'TCP'] + # Validate IP versions + ipvs = ['ipv4', 'ipv6'] + if ipv4_only and not ipv6_only: + ipvs = ['ipv4',] + elif ipv6_only and not ipv4_only: + ipvs = ['ipv6',] - for protocol in protocols: - if upnp and port not in firewall['uPnP'][protocol]: - firewall['uPnP'][protocol].append(port) - if port not in firewall[ipv][protocol]: - firewall[ipv][protocol].append(port) - else: - msignals.display(m18n.n('port_already_opened', port), 'warning') + for p in protocols: + # Iterate over IP versions to add port + for i in ipvs: + if port not in firewall[i][p]: + firewall[i][p].append(port) + else: + ipv = "IPv%s" % i[3] + msignals.display(m18n.n('port_already_opened', port, ipv), + 'warning') + # Add port forwarding with UPnP + if not no_upnp and port not in firewall['uPnP'][p]: + firewall['uPnP'][p].append(port) - with open(firewall_file, 'w') as f: - yaml.safe_dump(firewall, f, default_flow_style=False) - - return firewall_reload() + # Update and reload firewall + _update_firewall_file(firewall) + if not no_reload: + return firewall_reload() -def firewall_disallow(port=None, protocol=['TCP'], ipv6=False): +def firewall_disallow(port, protocol='TCP', ipv4_only=False, ipv6_only=False, + upnp_only=False, no_reload=False): """ - Allow connection port/protocol + Disallow connections on a port - Keyword argument: - port -- Port to open - protocol -- Protocol associated with port - ipv6 -- ipv6 + Keyword arguments: + port -- Port or range of ports to close + protocol -- Protocol type to disallow (default: TCP) + ipv4_only -- Only remove the rule for IPv4 connections + ipv6_only -- Only remove the rule for IPv6 connections + upnp_only -- Only remove forwarding of this port with UPnP + no_reload -- Do not reload firewall rules """ - port = int(port) - ipv = "ipv4" - if isinstance(protocol, list): - protocols = protocol - else: - protocols = [protocol] - protocol = protocols[0] - firewall = firewall_list(raw=True) - if ipv6: - ipv = "ipv6" + # Validate port + if ':' not in port: + port = int(port) - if protocol == "Both": - protocols = ['UDP', 'TCP'] + # Validate protocols + protocols = ['TCP', 'UDP'] + if protocol != 'Both' and protocol in protocols: + protocols = [protocol,] - for protocol in protocols: - if port in firewall['uPnP'][protocol]: - firewall['uPnP'][protocol].remove(port) - if port in firewall[ipv][protocol]: - firewall[ipv][protocol].remove(port) - else: - msignals.display(m18n.n('port_already_closed', port), 'warning') + # Validate IP versions and UPnP + ipvs = ['ipv4', 'ipv6'] + upnp = True + if ipv4_only and ipv6_only: + upnp = True # automatically disallow UPnP + elif ipv4_only: + ipvs = ['ipv4',] + upnp = upnp_only + elif ipv6_only: + ipvs = ['ipv6',] + upnp = upnp_only + elif upnp_only: + ipvs = [] - with open(firewall_file, 'w') as f: - yaml.safe_dump(firewall, f, default_flow_style=False) + for p in protocols: + # Iterate over IP versions to remove port + for i in ipvs: + if port in firewall[i][p]: + firewall[i][p].remove(port) + else: + ipv = "IPv%s" % i[3] + msignals.display(m18n.n('port_already_closed', port, ipv), + 'warning') + # Remove port forwarding with UPnP + if upnp and port in firewall['uPnP'][p]: + firewall['uPnP'][p].remove(port) - return firewall_reload() + # Update and reload firewall + _update_firewall_file(firewall) + if not no_reload: + return firewall_reload() -def firewall_list(raw=False): +def firewall_list(raw=False, by_ip_version=False, list_forwarded=False): """ List all firewall rules - Keyword argument: + Keyword arguments: raw -- Return the complete YAML dict + by_ip_version -- List rules by IP version + list_forwarded -- List forwarded ports with UPnP """ with open(firewall_file) as f: firewall = yaml.load(f) - if raw: return firewall - else: - return { "openned_ports": firewall['ipv4']['TCP'] } + + # Retrieve all ports for IPv4 and IPv6 + ports = {} + for i in ['ipv4', 'ipv6']: + f = firewall[i] + # Combine TCP and UDP ports + ports[i] = sorted(set(f['TCP']) | set(f['UDP'])) + + if not by_ip_version: + # Combine IPv4 and IPv6 ports + ports = sorted(set(ports['ipv4']) | set(ports['ipv6'])) + + # Format returned dict + ret = { "opened_ports": ports } + if list_forwarded: + # Combine TCP and UDP forwarded ports + ret['forwarded_ports'] = sorted( + set(firewall['uPnP']['TCP']) | set(firewall['uPnP']['UDP'])) + return ret def firewall_reload(): @@ -150,57 +196,93 @@ def firewall_reload(): """ from yunohost.hook import hook_callback - firewall = firewall_list(raw=True) - upnp = firewall['uPnP']['enabled'] + reloaded = False + errors = False + + # Check if SSH port is allowed ssh_port = _get_ssh_port() + if ssh_port not in firewall_list()['opened_ports']: + firewall_allow(ssh_port, no_reload=True) + + # Retrieve firewall rules and UPnP status + firewall = firewall_list(raw=True) + upnp = firewall_upnp()['enabled'] # IPv4 - if os.system("iptables -P INPUT ACCEPT") != 0: - raise MoulinetteError(errno.ESRCH, m18n.n('iptables_unavailable')) - if upnp: - firewall_upnp(no_refresh=False) + try: + process.check_output("iptables -L") + except process.CalledProcessError as e: + logger.info('iptables seems to be not available, it outputs:\n%s', + prependlines(e.output.rstrip(), '> ')) + msignals.display(m18n.n('iptables_unavailable'), 'info') + else: + rules = [ + "iptables -F", + "iptables -X", + "iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT", + ] + # Iterate over ports and add rule + for protocol in ['TCP', 'UDP']: + for port in firewall['ipv4'][protocol]: + rules.append("iptables -A INPUT -p %s --dport %s -j ACCEPT" \ + % (protocol, process.quote(str(port)))) + rules += [ + "iptables -A INPUT -i lo -j ACCEPT", + "iptables -A INPUT -p icmp -j ACCEPT", + "iptables -P INPUT DROP", + ] - os.system("iptables -F") - os.system("iptables -X") - os.system("iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT") + # Execute each rule + if process.check_commands(rules, callback=_on_rule_command_error): + errors = True + reloaded = True - if ssh_port not in firewall['ipv4']['TCP']: - firewall_allow(ssh_port) + # IPv6 + try: + process.check_output("ip6tables -L") + except process.CalledProcessError as e: + logger.info('ip6tables seems to be not available, it outputs:\n%s', + prependlines(e.output.rstrip(), '> ')) + msignals.display(m18n.n('ip6tables_unavailable'), 'info') + else: + rules = [ + "ip6tables -F", + "ip6tables -X", + "ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT", + ] + # Iterate over ports and add rule + for protocol in ['TCP', 'UDP']: + for port in firewall['ipv6'][protocol]: + rules.append("ip6tables -A INPUT -p %s --dport %s -j ACCEPT" \ + % (protocol, process.quote(str(port)))) + rules += [ + "ip6tables -A INPUT -i lo -j ACCEPT", + "ip6tables -A INPUT -p icmpv6 -j ACCEPT", + "ip6tables -P INPUT DROP", + ] - # Loop - for protocol in ['TCP', 'UDP']: - for port in firewall['ipv4'][protocol]: - os.system("iptables -A INPUT -p %s --dport %d -j ACCEPT" % (protocol, port)) + # Execute each rule + if process.check_commands(rules, callback=_on_rule_command_error): + errors = True + reloaded = True + + if not reloaded: + raise MoulinetteError(errno.ESRCH, m18n.n('firewall_reload_failed')) hook_callback('post_iptable_rules', args=[upnp, os.path.exists("/proc/net/if_inet6")]) - os.system("iptables -A INPUT -i lo -j ACCEPT") - os.system("iptables -A INPUT -p icmp -j ACCEPT") - os.system("iptables -P INPUT DROP") - - # IPv6 - if os.path.exists("/proc/net/if_inet6"): - os.system("ip6tables -P INPUT ACCEPT") - os.system("ip6tables -F") - os.system("ip6tables -X") - os.system("ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT") - - if ssh_port not in firewall['ipv6']['TCP']: - firewall_allow(ssh_port, ipv6=True) - - # Loop v6 - for protocol in ['TCP', 'UDP']: - for port in firewall['ipv6'][protocol]: - os.system("ip6tables -A INPUT -p %s --dport %d -j ACCEPT" % (protocol, port)) - - os.system("ip6tables -A INPUT -i lo -j ACCEPT") - os.system("ip6tables -A INPUT -p icmpv6 -j ACCEPT") - os.system("ip6tables -P INPUT DROP") + if upnp: + # Refresh port forwarding with UPnP + firewall_upnp(no_refresh=False) + # TODO: Use service_restart os.system("service fail2ban restart") - msignals.display(m18n.n('firewall_reloaded'), 'success') + if errors: + msignals.display(m18n.n('firewall_rules_cmd_failed'), 'warning') + else: + msignals.display(m18n.n('firewall_reloaded'), 'success') return firewall_list() @@ -349,3 +431,16 @@ def _get_ssh_port(default=22): except: pass return default + +def _update_firewall_file(rules): + """Make a backup and write new rules to firewall file""" + os.system("cp {0} {0}.old".format(firewall_file)) + with open(firewall_file, 'w') as f: + yaml.safe_dump(rules, f, default_flow_style=False) + +def _on_rule_command_error(returncode, cmd, output): + """Callback for rules commands error""" + # Log error and continue commands execution + logger.error('"%s" returned non-zero exit status %d:\n%s', + cmd, returncode, prependlines(output.rstrip(), '> ')) + return True diff --git a/locales/en.json b/locales/en.json index 121f5a0a4..c829c5d94 100644 --- a/locales/en.json +++ b/locales/en.json @@ -68,15 +68,18 @@ "dyndns_cron_remove_failed" : "Unable to remove DynDNS cron job", "dyndns_cron_removed" : "DynDNS cron job successfully removed", - "port_available" : "Port {:d} is available", - "port_unavailable" : "Port {:d} is not available", - "port_already_opened" : "Port {:d} is already opened", - "port_already_closed" : "Port {:d} is already closed", + "port_available" : "Port {} is available", + "port_unavailable" : "Port {} is not available", + "port_already_opened" : "Port {} is already opened for {:s} connections", + "port_already_closed" : "Port {} is already closed for {:s} connections", "iptables_unavailable" : "You cannot play with iptables here. You are either in a container or your kernel does not support it.", + "ip6tables_unavailable" : "You cannot play with ip6tables here. You are either in a container or your kernel does not support it.", "upnp_dev_not_found" : "No UPnP device found", "upnp_port_open_failed" : "Unable to open UPnP ports", "upnp_enabled" : "UPnP successfully enabled", "upnp_disabled" : "UPnP successfully disabled", + "firewall_rules_cmd_failed" : "Some firewall rules commands have failed. For more information, see the log.", + "firewall_reload_failed" : "Unable to reload firewall", "firewall_reloaded" : "Firewall successfully reloaded", "hook_list_by_invalid" : "Invalid property to list hook by", @@ -181,6 +184,7 @@ "pattern_domain" : "Must be a valid domain name (e.g. my-domain.org)", "pattern_listname" : "Must be alphanumeric and underscore characters only", "pattern_port" : "Must be a valid port number (i.e. 0-65535)", + "pattern_port_or_range" : "Must be a valid port number (i.e. 0-65535) or range of ports (e.g. 100:200)", "pattern_backup_archive_name" : "Must be a valid filename with alphanumeric and -_. characters only", "format_datetime_short" : "%m/%d/%Y %I:%M %p" diff --git a/locales/fr.json b/locales/fr.json index 268c902d0..43c74bba3 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -68,15 +68,18 @@ "dyndns_cron_remove_failed" : "Impossible d'enlever la tâche cron pour DynDNS", "dyndns_cron_removed" : "Tâche cron pour DynDNS enlevée avec succès", - "port_available" : "Le port {:d} est disponible", - "port_unavailable" : "Le port {:d} est indisponible", - "port_already_opened" : "Le port {:d} est déjà ouvert", - "port_already_closed" : "Le port {:d} est déjà fermé", + "port_available" : "Le port {} est disponible", + "port_unavailable" : "Le port {} est indisponible", + "port_already_opened" : "Le port {} est déjà ouvert pour l'{:s}", + "port_already_closed" : "Le port {} est déjà fermé pour l'{:s}", "iptables_unavailable" : "Vous ne pouvez pas faire joujou avec iptables ici. Vous êtes sûrement dans un conteneur, autrement votre noyau ne le supporte pas.", + "ip6tables_unavailable" : "Vous ne pouvez pas faire joujou avec ip6tables ici. Vous êtes sûrement dans un conteneur, autrement votre noyau ne le supporte pas.", "upnp_dev_not_found" : "Aucun périphérique compatible UPnP trouvé", "upnp_port_open_failed" : "Impossible d'ouvrir les ports avec UPnP", "upnp_enabled" : "UPnP activé avec succès", "upnp_disabled" : "UPnP désactivé avec succès", + "firewall_rules_cmd_failed" : "Des commandes de règles du pare-feu ont échoués. Plus d'informations sont disponibles dans le journal d'erreurs.", + "firewall_reload_failed" : "Impossible de recharger le pare-feu", "firewall_reloaded" : "Pare-feu rechargé avec succès", "hook_list_by_invalid" : "Propriété pour lister les scripts incorrecte", @@ -181,6 +184,7 @@ "pattern_domain" : "Doit être un nom de domaine valide (ex : mon-domaine.org)", "pattern_listname" : "Doit être composé uniquement de caractères alphanumérique et de tiret bas", "pattern_port" : "Doit être un numéro de port valide (0-65535)", + "pattern_port_or_range" : "Doit être un numéro de port valide (0-65535) ou une gamme de ports (ex : 100:200)", "pattern_backup_archive_name" : "Doit être un nom de fichier valide composé de caractères alphanumérique et -_. uniquement", "format_datetime_short" : "%d/%m/%Y %H:%M" From 4d7a7a331ea7ad6f4541ad8836c1724087c03f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Fri, 16 Jan 2015 00:51:38 +0100 Subject: [PATCH 06/10] [fix] Correct call to tools_adminpw in tools_postinstall --- tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools.py b/tools.py index 173a4fee0..fb09935e9 100644 --- a/tools.py +++ b/tools.py @@ -316,7 +316,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False): app_ssowatconf(auth) # Change LDAP admin password - tools_adminpw(old_password='yunohost', new_password=password) + tools_adminpw(auth, password) # Enable UPnP silently and reload firewall firewall_upnp('enable', no_refresh=True) From 7ad9831e3b1e9a38b9fb4b41938451cb2cf69ff8 Mon Sep 17 00:00:00 2001 From: Julien Malik Date: Sat, 31 Jan 2015 20:49:47 +0100 Subject: [PATCH 07/10] [enh] remove reference to tahoe --- data/services.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/data/services.yml b/data/services.yml index e699c7b6a..59fe141d5 100644 --- a/data/services.yml +++ b/data/services.yml @@ -18,9 +18,6 @@ mysql: log: [/var/log/mysql.log,/var/log/mysql.err] glances: status: service -tahoe-lafs: - status: ps aux | grep tahoe |grep -v grep - log: /home/yunohost.backup/tahoe/logs/twistd.log ssh: status: service log: /var/log/auth.log From 3a76e95c7f2e322140961f53ef8f0d27a6e44f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Sat, 31 Jan 2015 23:34:18 +0100 Subject: [PATCH 08/10] [enh] Add debian subdirectory and change root yolo structure --- actionsmap/yunohost.yml | 1207 ----------------- {hooks => data/hooks}/backup/05-system_ldap | 0 {hooks => data/hooks}/backup/08-system_ssh | 0 {hooks => data/hooks}/backup/11-system_mysql | 0 {hooks => data/hooks}/backup/14-system_ssowat | 0 {hooks => data/hooks}/backup/17-system_home | 0 .../hooks}/backup/20-system_yunohost | 0 {hooks => data/hooks}/backup/23-system_mail | 0 {hooks => data/hooks}/backup/26-system_xmpp | 0 {hooks => data/hooks}/backup/29-system_nginx | 0 {hooks => data/hooks}/backup/32-system_cron | 0 {hooks => data/hooks}/restore/05-system_ldap | 0 {hooks => data/hooks}/restore/08-system_ssh | 0 {hooks => data/hooks}/restore/11-system_mysql | 0 .../hooks}/restore/14-system_ssowat | 0 {hooks => data/hooks}/restore/17-system_home | 0 .../hooks}/restore/20-system_yunohost | 0 {hooks => data/hooks}/restore/23-system_mail | 0 {hooks => data/hooks}/restore/26-system_xmpp | 0 {hooks => data/hooks}/restore/29-system_nginx | 0 {hooks => data/hooks}/restore/32-system_cron | 0 data/{ => other}/checkupdate | 0 data/{ => other}/firewall.yml | 0 data/{ => other}/ldap_scheme.yml | 0 data/{ => other}/services.yml | 0 data/{ => other}/upgrade | 0 debian/changelog | 471 +++++++ debian/compat | 1 + debian/control | 21 + debian/copyright | 339 +++++ debian/install | 6 + debian/moulinette-yunohost.yunohost-api.init | 74 + debian/postinst | 56 + debian/preinst | 11 + debian/rules | 11 + debian/source/format | 1 + __init__.py => lib/yunohost/__init__.py | 0 app.py => lib/yunohost/app.py | 0 backup.py => lib/yunohost/backup.py | 0 domain.py => lib/yunohost/domain.py | 0 dyndns.py => lib/yunohost/dyndns.py | 0 firewall.py => lib/yunohost/firewall.py | 0 hook.py => lib/yunohost/hook.py | 0 monitor.py => lib/yunohost/monitor.py | 0 service.py => lib/yunohost/service.py | 0 tools.py => lib/yunohost/tools.py | 0 user.py => lib/yunohost/user.py | 0 47 files changed, 991 insertions(+), 1207 deletions(-) delete mode 100644 actionsmap/yunohost.yml rename {hooks => data/hooks}/backup/05-system_ldap (100%) rename {hooks => data/hooks}/backup/08-system_ssh (100%) rename {hooks => data/hooks}/backup/11-system_mysql (100%) rename {hooks => data/hooks}/backup/14-system_ssowat (100%) rename {hooks => data/hooks}/backup/17-system_home (100%) rename {hooks => data/hooks}/backup/20-system_yunohost (100%) rename {hooks => data/hooks}/backup/23-system_mail (100%) rename {hooks => data/hooks}/backup/26-system_xmpp (100%) rename {hooks => data/hooks}/backup/29-system_nginx (100%) rename {hooks => data/hooks}/backup/32-system_cron (100%) rename {hooks => data/hooks}/restore/05-system_ldap (100%) rename {hooks => data/hooks}/restore/08-system_ssh (100%) rename {hooks => data/hooks}/restore/11-system_mysql (100%) rename {hooks => data/hooks}/restore/14-system_ssowat (100%) rename {hooks => data/hooks}/restore/17-system_home (100%) rename {hooks => data/hooks}/restore/20-system_yunohost (100%) rename {hooks => data/hooks}/restore/23-system_mail (100%) rename {hooks => data/hooks}/restore/26-system_xmpp (100%) rename {hooks => data/hooks}/restore/29-system_nginx (100%) rename {hooks => data/hooks}/restore/32-system_cron (100%) rename data/{ => other}/checkupdate (100%) rename data/{ => other}/firewall.yml (100%) rename data/{ => other}/ldap_scheme.yml (100%) rename data/{ => other}/services.yml (100%) rename data/{ => other}/upgrade (100%) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/install create mode 100755 debian/moulinette-yunohost.yunohost-api.init create mode 100644 debian/postinst create mode 100644 debian/preinst create mode 100755 debian/rules create mode 100644 debian/source/format rename __init__.py => lib/yunohost/__init__.py (100%) rename app.py => lib/yunohost/app.py (100%) rename backup.py => lib/yunohost/backup.py (100%) rename domain.py => lib/yunohost/domain.py (100%) rename dyndns.py => lib/yunohost/dyndns.py (100%) rename firewall.py => lib/yunohost/firewall.py (100%) rename hook.py => lib/yunohost/hook.py (100%) rename monitor.py => lib/yunohost/monitor.py (100%) rename service.py => lib/yunohost/service.py (100%) rename tools.py => lib/yunohost/tools.py (100%) rename user.py => lib/yunohost/user.py (100%) diff --git a/actionsmap/yunohost.yml b/actionsmap/yunohost.yml deleted file mode 100644 index ca5ce6d3a..000000000 --- a/actionsmap/yunohost.yml +++ /dev/null @@ -1,1207 +0,0 @@ -########################################################################## -# Category/actions/arguments file -# -# -# Except for general_arguments, this file contains 3 levels -# as in this sample command line: -# -# yunohost monitor info --cpu --ram -# ^ ^ ^ ^ -# (script) | category | action | parameters -# -# -# Above example will lead to the function 'monitor_info(args)' -# in the file 'yunohost_monitor.py' with 'cpu' and 'ram' -# stored in an 'args' dictionnary. -# -# Usage: -# You can add a category at the first level, action at the second one, -# and arguments at the third one. -# If a connexion is needed for the action, don't forget to add it to -# the action parameters (ldap, repo, dns or firewall). -# -# Documentation: -# You can see all arguments settings at the argparse documentation: -# http://docs.python.org/dev/library/argparse.html -# #argparse.ArgumentParser.add_argument -# -# Don't forget to turn argument yaml style (setting: value) -# -########################################################################## - -############################# -# Global parameters # -############################# -_global: - configuration: - authenticate: - - api - authenticator: - default: - vendor: ldap - help: admin_password - parameters: - uri: ldap://localhost:389 - base_dn: dc=yunohost,dc=org - user_rdn: cn=admin - ldap-anonymous: - vendor: ldap - parameters: - uri: ldap://localhost:389 - base_dn: dc=yunohost,dc=org - argument_auth: true - lock: true - arguments: - -v: - full: --version - help: Display moulinette version - action: version - version: moulinette %version% - -############################# -# User # -############################# -user: - category_help: Manage users - actions: - - ### user_list() - list: - action_help: List users - api: GET /users - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - --fields: - help: fields to fetch - nargs: "+" - -f: - full: --filter - help: LDAP filter used to search - -l: - full: --limit - help: Maximum number of user fetched - type: int - -o: - full: --offset - help: Starting number for user fetching - type: int - - ### user_create() - create: - action_help: Create user - api: POST /users - configuration: - authenticate: all - arguments: - username: - help: The unique username to create - extra: - pattern: &pattern_username - - !!str ^[a-z0-9_]+$ - - "pattern_username" - -f: - full: --firstname - extra: - ask: ask_firstname - required: True - pattern: &pattern_firstname - - !!str ^([^\W\d_]{2,30}[ ,.'-]{0,3})+$ - - "pattern_firstname" - -l: - full: --lastname - extra: - ask: ask_lastname - required: True - pattern: &pattern_lastname - - !!str ^([^\W\d_]{2,30}[ ,.']{0,3})+$ - - "pattern_lastname" - -m: - full: --mail - help: Main unique email address - extra: - ask: ask_email - required: True - pattern: &pattern_email - - !!str ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$ - - "pattern_email" - -p: - full: --password - help: User password - extra: - password: ask_password - required: True - pattern: &pattern_password - - !!str ^.{3,}$ - - "pattern_password" - - ### user_delete() - delete: - action_help: Delete user - api: DELETE /users/ - configuration: - authenticate: all - arguments: - username: - help: Username to delete - extra: - pattern: *pattern_username - --purge: - action: store_true - - ### user_update() - update: - action_help: Update user informations - api: PUT /users/ - configuration: - authenticate: all - arguments: - username: - help: Username to update - -f: - full: --firstname - extra: - pattern: *pattern_firstname - -l: - full: --lastname - extra: - pattern: *pattern_lastname - -m: - full: --mail - extra: - pattern: *pattern_email - -p: - full: --change-password - help: New password to set - metavar: PASSWORD - extra: - pattern: *pattern_password - --add-mailforward: - help: Mailforward addresses to add - nargs: "*" - metavar: MAIL - extra: - pattern: *pattern_email - --remove-mailforward: - help: Mailforward addresses to remove - nargs: "*" - metavar: MAIL - --add-mailalias: - help: Mail aliases to add - nargs: "*" - metavar: MAIL - extra: - pattern: *pattern_email - --remove-mailalias: - help: Mail aliases to remove - nargs: "*" - metavar: MAIL - - ### user_info() - info: - action_help: Get user information - api: GET /users/ - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - username: - help: Username or email to get information - - -############################# -# Domain # -############################# -domain: - category_help: Manage domains - actions: - - ### domain_list() - list: - action_help: List domains - api: GET /domains - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - -f: - full: --filter - help: LDAP filter used to search - -l: - full: --limit - help: Maximum number of domain fetched - type: int - -o: - full: --offset - help: Starting number for domain fetching - type: int - - ### domain_add() - add: - action_help: Create a custom domain - api: POST /domains - configuration: - authenticate: all - arguments: - domain: - help: Domain name to add - extra: - pattern: &pattern_domain - - !!str ^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+[a-z]{2,}$ - - "pattern_domain" - -d: - full: --dyndns - help: Subscribe to the DynDNS service - action: store_true - - ### domain_remove() - remove: - action_help: Delete domains - api: DELETE /domains/ - configuration: - authenticate: all - arguments: - domain: - help: Domain to delete - extra: - pattern: *pattern_domain - - ### domain_info() -# info: -# action_help: Get domain informations -# api: GET /domains/ -# arguments: -# domain: -# help: "" -# extra: -# pattern: -# - '^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$' -# - "Must be a valid domain name (e.g. my-domain.org)" - - -############################# -# App # -############################# -app: - category_help: Manage apps - actions: - - ### app_fetchlist() - fetchlist: - action_help: Fetch application list from app server - api: PUT /appslists - arguments: - -u: - full: --url - help: URL of remote JSON list (default http://fapp.yunohost.org/app/list/raw) - -n: - full: --name - help: Name of the list (default fapp) - extra: - pattern: &pattern_listname - - !!str ^[a-z0-9_]+$ - - "pattern_listname" - - ### app_listlists() - listlists: - action_help: List fetched lists - api: GET /appslists - - ### app_removelist() - removelist: - action_help: Remove list from the repositories - api: DELETE /appslists - arguments: - name: - help: Name of the list to remove - extra: - ask: ask_list_to_remove - pattern: *pattern_listname - - ### app_list() - list: - action_help: List apps - api: GET /apps - arguments: - -l: - full: --limit - help: Maximum number of app fetched - -o: - full: --offset - help: Starting number for app fetching - -f: - full: --filter - help: Name filter of app_id or app_name - -r: - full: --raw - help: Return the full app_dict - action: store_true - - ### app_info() - info: - action_help: Get app info - api: GET /apps/ - arguments: - app: - help: Specific app ID - -r: - full: --raw - help: Return the full app_dict - action: store_true - - ### app_map() - map: - action_help: List apps by domain - api: GET /appsmap - arguments: - -a: - full: --app - help: Specific app to map - -r: - full: --raw - help: Return complete dict - action: store_true - -u: - full: --user - help: Allowed app map for a user - extra: - pattern: *pattern_username - - ### app_install() - install: - action_help: Install apps - api: POST /apps - configuration: - authenticate: all - authenticator: ldap-anonymous - lock: false - arguments: - app: - help: Name, local path or git URL of the app to install - -l: - full: --label - help: Custom name for the app - -a: - full: --args - help: Serialize arguments for app installation - - ### app_remove() TODO: Write help - remove: - action_help: Remove app - api: DELETE /apps/ - configuration: - authenticate: all - authenticator: ldap-anonymous - lock: false - arguments: - app: - help: App(s) to delete - - ### app_upgrade() - upgrade: - action_help: Upgrade app - api: PUT /upgrade/apps - configuration: - authenticate: all - authenticator: ldap-anonymous - lock: false - arguments: - app: - help: App(s) to upgrade (default all) - nargs: "*" - -u: - full: --url - help: Git url to fetch for upgrade - -f: - full: --file - help: Folder or tarball for upgrade - - ### app_setting() - setting: - action_help: Set ou get an app setting value - api: GET /apps//settings - arguments: - app: - help: App ID - key: - help: Key to get/set - -v: - full: --value - help: Value to set - -d: - full: --delete - help: Delete the key - action: store_true - - ### app_checkport() - checkport: - action_help: Check availability of a local port - api: GET /tools/checkport - arguments: - port: - help: Port to check - extra: - pattern: &pattern_port - - !!str ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$ - - "pattern_port" - - ### app_checkurl() - checkurl: - action_help: Check availability of a web path - api: GET /tools/checkurl - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - url: - help: Url to check - -a: - full: --app - help: Write domain & path to app settings for further checks - - ### app_initdb() - initdb: - action_help: Create database and initialize it with optionnal attached script - api: POST /tools/initdb - arguments: - user: - help: Name of the DB user - -p: - full: --password - help: Password of the DB (generated unless set) - -d: - full: --db - help: DB name (user unless set) - -s: - full: --sql - help: Initial SQL file - - ### app_makedefault() - makedefault: - action_help: Redirect domain root to an app - api: PUT /apps//default - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - app: - help: App name to put on domain root - -d: - full: --domain - help: Specific domain to put app on (the app domain by default) - - ### app_ssowatconf() - ssowatconf: - action_help: Regenerate SSOwat configuration file - api: PUT /ssowatconf - configuration: - authenticate: all - authenticator: ldap-anonymous - - ### app_addaccess() TODO: Write help - addaccess: - action_help: Grant access right to users (everyone by default) - api: PUT /access - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - apps: - nargs: "+" - -u: - full: --users - nargs: "+" - - ### app_removeaccess() TODO: Write help - removeaccess: - action_help: Revoke access right to users (everyone by default) - api: DELETE /access - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - apps: - nargs: "+" - -u: - full: --users - nargs: "+" - - ### app_clearaccess() - clearaccess: - action_help: Reset access rights for the app - api: POST /access - configuration: - authenticate: all - authenticator: ldap-anonymous - arguments: - apps: - nargs: "+" - -############################# -# Backup # -############################# -backup: - category_help: Manage backups - actions: - - ### backup_create() - create: - action_help: Create a backup local archive - api: POST /backup - configuration: - lock: false - arguments: - -n: - full: --name - help: Name of the backup archive - extra: - pattern: &pattern_backup_archive_name - - !!str ^[\w\-\.]{1,30}(? - configuration: - lock: false - arguments: - name: - help: Name of the local backup archive - - -############################# -# Monitor # -############################# -monitor: - category_help: Monitor the server - actions: - - ### monitor_disk() - disk: - action_help: Monitor disk space and usage - api: GET /monitor/disk - arguments: - -f: - full: --filesystem - help: Show filesystem disk space - action: append_const - const: filesystem - dest: units - -t: - full: --io - help: Show I/O throughput - action: append_const - const: io - dest: units - -m: - full: --mountpoint - help: Monitor only the device mounted on MOUNTPOINT - action: store - -H: - full: --human-readable - help: Print sizes in human readable format - action: store_true - - ### monitor_network() - network: - action_help: Monitor network interfaces - api: GET /monitor/network - arguments: - -u: - full: --usage - help: Show interfaces bit rates - action: append_const - const: usage - dest: units - -i: - full: --infos - help: Show network informations - action: append_const - const: infos - dest: units - -H: - full: --human-readable - help: Print sizes in human readable format - action: store_true - - ### monitor_system() - system: - action_help: Monitor system informations and usage - api: GET /monitor/system - arguments: - -m: - full: --memory - help: Show memory usage - action: append_const - const: memory - dest: units - -c: - full: --cpu - help: Show CPU usage and load - action: append_const - const: cpu - dest: units - -p: - full: --process - help: Show processes summary - action: append_const - const: process - dest: units - -u: - full: --uptime - help: Show the system uptime - action: append_const - const: uptime - dest: units - -i: - full: --infos - help: Show system informations - action: append_const - const: infos - dest: units - -H: - full: --human-readable - help: Print sizes in human readable format - action: store_true - - ### monitor_updatestats() - update-stats: - action_help: Update monitoring statistics - api: POST /monitor/stats - arguments: - period: - help: Time period to update - choices: - - day - - week - - month - - ### monitor_showstats() - show-stats: - action_help: Show monitoring statistics - api: GET /monitor/stats - arguments: - period: - help: Time period to show - choices: - - day - - week - - month - - ### monitor_enable() - enable: - action_help: Enable server monitoring - api: PUT /monitor - arguments: - -n: - full: --no-stats - help: Disable monitoring statistics - action: store_true - - ### monitor_disable() - disable: - api: DELETE /monitor - action_help: Disable server monitoring - - -############################# -# Service # -############################# -service: - category_help: Manage services - actions: - - ### service_add() - add: - action_help: Add a service - # api: POST /services - arguments: - name: - help: Service name to add - -s: - full: --status - help: Custom status command - -l: - full: --log - help: Absolute path to log file to display - nargs: "+" - -r: - full: --runlevel - help: Runlevel priority of the service - type: int - - ### service_remove() - remove: - action_help: Remove a service - # api: DELETE /services - arguments: - name: - help: Service name to remove - - ### service_start() - start: - action_help: Start one or more services - api: PUT /services/ - arguments: - names: - help: Service name to start - nargs: "+" - metavar: NAME - - ### service_stop() - stop: - action_help: Stop one or more services - api: DELETE /services/ - arguments: - names: - help: Service name to stop - nargs: "+" - metavar: NAME - - ### service_enable() - enable: - action_help: Enable one or more services - api: PUT /services//enable - arguments: - names: - help: Service name to enable - nargs: "+" - metavar: NAME - - ### service_disable() - disable: - action_help: Disable one or more services - api: DELETE /services//enable - arguments: - names: - help: Service name to disable - nargs: "+" - metavar: NAME - - ### service_status() - status: - action_help: Show status information about one or more services (all by default) - api: - - GET /services - - GET /services/ - arguments: - names: - help: Service name to show - nargs: "*" - metavar: NAME - - ### service_log() - log: - action_help: Log every log files of a service - api: GET /services//log - arguments: - name: - help: Service name to log - -n: - full: --number - help: Number of lines to display - default: 50 - type: int - - -############################# -# Firewall # -############################# -firewall: - category_help: Manage firewall rules - actions: - - ### firewall_list() - list: - action_help: List all firewall rules - api: GET /firewall - arguments: - -r: - full: --raw - help: Return the complete YAML dict - action: store_true - -i: - full: --by-ip-version - help: List rules by IP version - action: store_true - -f: - full: --list-forwarded - help: List forwarded ports with UPnP - action: store_true - - ### firewall_reload() - reload: - action_help: Reload all firewall rules - api: PUT /firewall - - ### firewall_allow() - allow: - action_help: Allow connections on a port - api: POST /firewall/port - arguments: - port: - help: Port or range of ports to open - extra: - pattern: &pattern_port_or_range - - !!str ((^|(?!\A):)([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){1,2}?$ - - "pattern_port_or_range" - -p: - full: --protocol - help: "Protocol type to allow (default: TCP)" - choices: - - TCP - - UDP - - Both - default: TCP - -4: - full: --ipv4-only - help: Only add a rule for IPv4 connections - action: store_true - -6: - full: --ipv6-only - help: Only add a rule for IPv6 connections - action: store_true - --no-upnp: - help: Do not add forwarding of this port with UPnP - action: store_true - --no-reload: - help: Do not reload firewall rules - action: store_true - - - ### firewall_disallow() - disallow: - action_help: Disallow connections on a port - api: DELETE /firewall/port - arguments: - port: - help: Port or range of ports to close - extra: - pattern: *pattern_port_or_range - -p: - full: --protocol - help: "Protocol type to allow (default: TCP)" - choices: - - TCP - - UDP - - Both - default: TCP - -4: - full: --ipv4-only - help: Only remove the rule for IPv4 connections - action: store_true - -6: - full: --ipv6-only - help: Only remove the rule for IPv6 connections - action: store_true - --upnp-only: - help: Only remove forwarding of this port with UPnP - action: store_true - --no-reload: - help: Do not reload firewall rules - action: store_true - - - ### firewall_upnp() - upnp: - action_help: Manage port forwarding using UPnP - api: GET /firewall/upnp - arguments: - action: - choices: - - enable - - disable - - status - - reload - nargs: "?" - default: status - --no-refresh: - help: Do not refresh port forwarding - action: store_true - - ### firewall_stop() - stop: - action_help: Stop iptables and ip6tables - api: DELETE /firewall - - - -############################# -# DynDNS # -############################# -dyndns: - category_help: Subscribe and Update DynDNS Hosts - actions: - - ### dyndns_subscribe() - subscribe: - action_help: Subscribe to a DynDNS service - api: POST /dyndns - arguments: - --subscribe-host: - help: Dynette HTTP API to subscribe to - default: "dyndns.yunohost.org" - -d: - full: --domain - help: Full domain to subscribe with - extra: - pattern: *pattern_domain - -k: - full: --key - help: Public DNS key - - ### dyndns_update() - update: - action_help: Update IP on DynDNS platform - api: PUT /dyndns - arguments: - --dyn-host: - help: Dynette DNS server to inform - default: "dynhost.yunohost.org" - -d: - full: --domain - help: Full domain to subscribe with - extra: - pattern: *pattern_domain - -k: - full: --key - help: Public DNS key - -i: - full: --ip - help: IP address to send - - ### dyndns_installcron() - installcron: - action_help: Install IP update cron - api: POST /dyndns/cron - - ### dyndns_removecron() - removecron: - action_help: Remove IP update cron - api: DELETE /dyndns/cron - - -############################# -# Tools # -############################# -tools: - category_help: Specific tools - actions: - - ### tools_ldapinit() - ldapinit: - action_help: YunoHost LDAP initialization - api: POST /ldap - configuration: - authenticate: all - - ### tools_adminpw() - adminpw: - action_help: Change admin password - api: PUT /adminpw - configuration: - authenticate: all - arguments: - -n: - full: --new-password - extra: - password: ask_new_admin_password - pattern: *pattern_password - required: True - - ### tools_maindomain() - maindomain: - action_help: Main domain change tool - api: PUT /domains/main - configuration: - authenticate: all - arguments: - -o: - full: --old-domain - extra: - pattern: *pattern_domain - -n: - full: --new-domain - extra: - pattern: *pattern_domain - - ### tools_postinstall() - postinstall: - action_help: YunoHost post-install - api: POST /postinstall - configuration: - authenticate: false - lock: false - arguments: - -d: - full: --domain - help: YunoHost main domain - extra: - ask: ask_main_domain - pattern: *pattern_domain - required: True - -p: - full: --password - help: YunoHost admin password - extra: - password: ask_new_admin_password - pattern: *pattern_password - required: True - --ignore-dyndns: - help: Do not subscribe domain to a DynDNS service - action: store_true - - ### tools_update() - update: - action_help: YunoHost update - api: PUT /update - configuration: - lock: false - arguments: - --ignore-apps: - help: Ignore apps cache update and changelog - action: store_true - --ignore-packages: - help: Ignore APT cache update and changelog - action: store_true - - ### tools_upgrade() - upgrade: - action_help: YunoHost upgrade - api: PUT /upgrade - configuration: - authenticate: all - authenticator: ldap-anonymous - lock: false - arguments: - --ignore-apps: - help: Ignore apps upgrade - action: store_true - --ignore-packages: - help: Ignore APT packages upgrade - action: store_true - - -############################# -# Hook # -############################# -hook: - category_help: Manage hooks - actions: - - ### hook_add() - add: - action_help: Store hook script to filesystem - api: PUT /hook - arguments: - app: - help: App to link with - file: - help: Script to add - - ### hook_remove() - remove: - action_help: Remove hook scripts from filesystem - api: DELETE /hook - arguments: - app: - help: Scripts related to app will be removed - - ### hook_list() - list: - action_help: List available hooks for an action - api: GET /hooks/ - arguments: - action: - help: Action name - -l: - full: --list-by - help: Property to list hook by - choices: - - name - - priority - - folder - default: name - -i: - full: --show-info - help: Show hook information - action: store_true - - ### hook_callback() - callback: - action_help: Execute all scripts binded to an action - api: GET /hooks - arguments: - action: - help: Action name - -n: - full: --hooks - help: List of hooks names to execute - nargs: "*" - -a: - full: --args - help: Ordered list of arguments to pass to the script - nargs: "*" - - ### hook_check() - check: - action_help: Parse the script file and get arguments - api: GET /hook/check - arguments: - file: - help: File 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/hooks/backup/05-system_ldap b/data/hooks/backup/05-system_ldap similarity index 100% rename from hooks/backup/05-system_ldap rename to data/hooks/backup/05-system_ldap diff --git a/hooks/backup/08-system_ssh b/data/hooks/backup/08-system_ssh similarity index 100% rename from hooks/backup/08-system_ssh rename to data/hooks/backup/08-system_ssh diff --git a/hooks/backup/11-system_mysql b/data/hooks/backup/11-system_mysql similarity index 100% rename from hooks/backup/11-system_mysql rename to data/hooks/backup/11-system_mysql diff --git a/hooks/backup/14-system_ssowat b/data/hooks/backup/14-system_ssowat similarity index 100% rename from hooks/backup/14-system_ssowat rename to data/hooks/backup/14-system_ssowat diff --git a/hooks/backup/17-system_home b/data/hooks/backup/17-system_home similarity index 100% rename from hooks/backup/17-system_home rename to data/hooks/backup/17-system_home diff --git a/hooks/backup/20-system_yunohost b/data/hooks/backup/20-system_yunohost similarity index 100% rename from hooks/backup/20-system_yunohost rename to data/hooks/backup/20-system_yunohost diff --git a/hooks/backup/23-system_mail b/data/hooks/backup/23-system_mail similarity index 100% rename from hooks/backup/23-system_mail rename to data/hooks/backup/23-system_mail diff --git a/hooks/backup/26-system_xmpp b/data/hooks/backup/26-system_xmpp similarity index 100% rename from hooks/backup/26-system_xmpp rename to data/hooks/backup/26-system_xmpp diff --git a/hooks/backup/29-system_nginx b/data/hooks/backup/29-system_nginx similarity index 100% rename from hooks/backup/29-system_nginx rename to data/hooks/backup/29-system_nginx diff --git a/hooks/backup/32-system_cron b/data/hooks/backup/32-system_cron similarity index 100% rename from hooks/backup/32-system_cron rename to data/hooks/backup/32-system_cron diff --git a/hooks/restore/05-system_ldap b/data/hooks/restore/05-system_ldap similarity index 100% rename from hooks/restore/05-system_ldap rename to data/hooks/restore/05-system_ldap diff --git a/hooks/restore/08-system_ssh b/data/hooks/restore/08-system_ssh similarity index 100% rename from hooks/restore/08-system_ssh rename to data/hooks/restore/08-system_ssh diff --git a/hooks/restore/11-system_mysql b/data/hooks/restore/11-system_mysql similarity index 100% rename from hooks/restore/11-system_mysql rename to data/hooks/restore/11-system_mysql diff --git a/hooks/restore/14-system_ssowat b/data/hooks/restore/14-system_ssowat similarity index 100% rename from hooks/restore/14-system_ssowat rename to data/hooks/restore/14-system_ssowat diff --git a/hooks/restore/17-system_home b/data/hooks/restore/17-system_home similarity index 100% rename from hooks/restore/17-system_home rename to data/hooks/restore/17-system_home diff --git a/hooks/restore/20-system_yunohost b/data/hooks/restore/20-system_yunohost similarity index 100% rename from hooks/restore/20-system_yunohost rename to data/hooks/restore/20-system_yunohost diff --git a/hooks/restore/23-system_mail b/data/hooks/restore/23-system_mail similarity index 100% rename from hooks/restore/23-system_mail rename to data/hooks/restore/23-system_mail diff --git a/hooks/restore/26-system_xmpp b/data/hooks/restore/26-system_xmpp similarity index 100% rename from hooks/restore/26-system_xmpp rename to data/hooks/restore/26-system_xmpp diff --git a/hooks/restore/29-system_nginx b/data/hooks/restore/29-system_nginx similarity index 100% rename from hooks/restore/29-system_nginx rename to data/hooks/restore/29-system_nginx diff --git a/hooks/restore/32-system_cron b/data/hooks/restore/32-system_cron similarity index 100% rename from hooks/restore/32-system_cron rename to data/hooks/restore/32-system_cron diff --git a/data/checkupdate b/data/other/checkupdate similarity index 100% rename from data/checkupdate rename to data/other/checkupdate diff --git a/data/firewall.yml b/data/other/firewall.yml similarity index 100% rename from data/firewall.yml rename to data/other/firewall.yml diff --git a/data/ldap_scheme.yml b/data/other/ldap_scheme.yml similarity index 100% rename from data/ldap_scheme.yml rename to data/other/ldap_scheme.yml diff --git a/data/services.yml b/data/other/services.yml similarity index 100% rename from data/services.yml rename to data/other/services.yml diff --git a/data/upgrade b/data/other/upgrade similarity index 100% rename from data/upgrade rename to data/other/upgrade diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..1ac730ec9 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,471 @@ +moulinette-yunohost (2.0-rc~megusta33) test; urgency=low + + * Test build: [enh] Use dnsmasq + + -- Adrien Beudin Wed, 24 Dec 2014 17:04:29 +0100 + +moulinette-yunohost (2.0-rc~megusta32) test; urgency=low + + * Test build: [enh] Replace udiskie by udisks-glue + + -- Adrien Beudin Fri, 31 Oct 2014 19:36:18 +0100 + +moulinette-yunohost (2.0-rc~megusta31) test; urgency=low + + * Test build: [enh] Working backup and restore + + -- Adrien Beudin Sun, 26 Oct 2014 00:50:34 +0200 + +moulinette-yunohost (2.0-rc~megusta30) test; urgency=low + + * Test build: Fixes + + -- Adrien Beudin Sun, 26 Oct 2014 00:16:21 +0200 + +moulinette-yunohost (2.0-rc~megusta29) test; urgency=low + + * Test build: Restore function WIP + + -- Adrien Beudin Sat, 25 Oct 2014 23:23:25 +0200 + +moulinette-yunohost (2.0-rc~megusta28) test; urgency=low + + * Test build: typo + + -- Adrien Beudin Sat, 25 Oct 2014 20:41:10 +0200 + +moulinette-yunohost (2.0-rc~megusta27) test; urgency=low + + * Test build: typo + + -- Adrien Beudin Sat, 25 Oct 2014 20:09:26 +0200 + +moulinette-yunohost (2.0-rc~megusta26) test; urgency=low + + * Test build: typo + + -- Adrien Beudin Sat, 25 Oct 2014 19:38:54 +0200 + +moulinette-yunohost (2.0-rc~megusta25) test; urgency=low + + * Test build: Backup / restore WIP + + -- Adrien Beudin Sat, 25 Oct 2014 18:58:03 +0200 + +moulinette-yunohost (2.0-rc~megusta24) test; urgency=low + + * Test build: [enh] add firewall init script + + -- Adrien Beudin Tue, 16 Sep 2014 14:29:10 +0200 + +moulinette-yunohost (2.0-rc~megusta23) test; urgency=low + + * Test build: [enh] Add avahi daemon + + -- Adrien Beudin Tue, 16 Sep 2014 09:43:51 +0200 + +moulinette-yunohost (2.0-rc~megusta22) megusta; urgency=low + + * Production build: Bump version + + -- Adrien Beudin Thu, 31 Jul 2014 12:31:32 +0200 + +moulinette-yunohost (2.0-rc~megusta21) megusta; urgency=low + + * Production build: Bump version + + -- Adrien Beudin Thu, 31 Jul 2014 12:09:57 +0200 + +moulinette-yunohost (2.0-rc~megusta20) test; urgency=low + + * Test build: Update from git 31ef39e4e + + -- Adrien Beudin Mon, 28 Jul 2014 18:09:50 +0200 + +moulinette-yunohost (2.0-rc~megusta19) megusta; urgency=low + + * Production build: bump version + + -- Adrien Beudin Mon, 21 Jul 2014 16:23:15 +0200 + +moulinette-yunohost (2.0-rc~megusta18) megusta; urgency=low + + * Production build: Fix upgrade and various fixes + + -- Adrien Beudin Mon, 21 Jul 2014 16:16:57 +0200 + +moulinette-yunohost (2.0-rc~megusta17) test; urgency=low + + * Test build: Various fixes + + -- Adrien Beudin Mon, 21 Jul 2014 16:10:40 +0200 + +moulinette-yunohost (2.0-rc~megusta16) test; urgency=low + + * Test build: Update from git fed3e6f67 + + -- Adrien Beudin Fri, 18 Jul 2014 18:37:44 +0200 + +moulinette-yunohost (2.0-rc~megusta15) megusta; urgency=low + + * Production build: Update from git 496b4910159d + + -- Adrien Beudin Tue, 01 Jul 2014 19:08:29 +0200 + +moulinette-yunohost (2.0-rc~megusta14) test; urgency=low + + * Test build: Update from git 496b4910159d + + -- Adrien Beudin Tue, 01 Jul 2014 19:01:33 +0200 + +moulinette-yunohost (2.0-rc~megusta13) test; urgency=low + + * Test build: [fix] Init script + + -- Adrien Beudin Mon, 30 Jun 2014 17:52:52 +0200 + +moulinette-yunohost (2.0-rc~megusta12) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 28 Jun 2014 15:07:05 +0200 + +moulinette-yunohost (2.0-rc~megusta11) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 28 Jun 2014 10:59:30 +0200 + +moulinette-yunohost (2.0-rc~megusta10) test; urgency=low + + * Test build: [fix] Properly separate upnp and firewall + + -- Adrien Beudin Thu, 26 Jun 2014 12:40:47 +0200 + +moulinette-yunohost (2.0-rc~megusta9) test; urgency=low + + * Test build: [fix] API init script + + -- Adrien Beudin Wed, 25 Jun 2014 22:31:51 +0200 + +moulinette-yunohost (2.0-rc~megusta8) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Tue, 24 Jun 2014 13:56:53 +0200 + +moulinette-yunohost (2.0-rc~megusta7) megusta; urgency=low + + * Production build: [fix] copy firewall.yml file + + -- Adrien Beudin Sat, 14 Jun 2014 13:42:34 +0200 + +moulinette-yunohost (2.0-rc~megusta6) megusta; urgency=low + + * Production build: [fix] Wrong translation key in app module + + -- Adrien Beudin Thu, 12 Jun 2014 19:13:54 +0200 + +moulinette-yunohost (2.0-rc~megusta5) test; urgency=low + + * Test build: [fix] Add --no-websocket option to yunohost-api when + gevent segfault + + -- Adrien Beudin Thu, 12 Jun 2014 09:51:56 +0200 + +moulinette-yunohost (2.0-rc~megusta4) test; urgency=low + + * Test build: [fix] Add --no-websocket option to yunohost-api when + gevent segfault + + -- Adrien Beudin Thu, 12 Jun 2014 09:43:13 +0200 + +moulinette-yunohost (2.0-rc~megusta3) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Thu, 12 Jun 2014 09:28:32 +0200 + +moulinette-yunohost (2.0-rc~megusta2) megusta; urgency=low + + * Production build: Bump version + + -- Adrien Beudin Mon, 09 Jun 2014 01:43:09 +0200 + +moulinette-yunohost (2.0-rc~megusta1) test; urgency=low + + * Bump version + + -- Adrien Beudin Mon, 09 Jun 2014 00:49:09 +0200 + +moulinette-yunohost (2.0~megusta44) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 09 Jun 2014 00:49:09 +0200 + +moulinette-yunohost (2.0~megusta43) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Fri, 06 Jun 2014 12:24:33 +0200 + +moulinette-yunohost (2.0~megusta42) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 02 Jun 2014 22:10:12 +0200 + +moulinette-yunohost (2.0~megusta41) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 02 Jun 2014 11:29:54 +0200 + +moulinette-yunohost (2.0~megusta40) test; urgency=low + + * Test build: [fix] Remove --no-ldap argument while fetching applist + + -- Adrien Beudin Sun, 01 Jun 2014 21:44:08 +0200 + +moulinette-yunohost (2.0~megusta39) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 31 May 2014 11:37:40 +0200 + +moulinette-yunohost (2.0~megusta38) test; urgency=low + + * Test build: [fix] Move udsikie init script + + -- Adrien Beudin Fri, 30 May 2014 13:37:38 +0200 + +moulinette-yunohost (2.0~megusta37) test; urgency=low + + * Test build: [fix] dependencies + + -- Adrien Beudin Thu, 29 May 2014 21:34:45 +0200 + +moulinette-yunohost (2.0~megusta36) test; urgency=low + + * Test build: [fix] dependencies + + -- Adrien Beudin Thu, 29 May 2014 21:21:52 +0200 + +moulinette-yunohost (2.0~megusta35) test; urgency=low + + * Test build: [fix] Install udiskie via pip + + -- Adrien Beudin Thu, 29 May 2014 10:48:21 +0200 + +moulinette-yunohost (2.0~megusta34) test; urgency=low + + * Test build: [fix] Install udiskie via pip + + -- Adrien Beudin Thu, 29 May 2014 10:20:24 +0200 + +moulinette-yunohost (2.0~megusta33) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Wed, 28 May 2014 21:05:27 +0200 + +moulinette-yunohost (2.0~megusta32) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Wed, 28 May 2014 15:38:24 +0200 + +moulinette-yunohost (2.0~megusta31) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Tue, 27 May 2014 14:44:24 +0200 + +moulinette-yunohost (2.0~megusta30) test; urgency=low + + * Test build: [fix] Reload SSOwat conf at postinst + + -- Adrien Beudin Tue, 27 May 2014 13:54:53 +0200 + +moulinette-yunohost (2.0~megusta29) test; urgency=low + + * Test build: [fix] Reload SSOwat conf at postinst + + -- Adrien Beudin Tue, 27 May 2014 13:51:08 +0200 + +moulinette-yunohost (2.0~megusta28) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Tue, 27 May 2014 12:44:06 +0200 + +moulinette-yunohost (2.0~megusta27) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 26 May 2014 13:40:28 +0200 + +moulinette-yunohost (2.0~megusta26) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 24 May 2014 21:33:08 +0200 + +moulinette-yunohost (2.0~megusta25) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 17:29:32 +0200 + +moulinette-yunohost (2.0~megusta24) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 17:28:57 +0200 + +moulinette-yunohost (2.0~megusta23) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 13:06:04 +0200 + +moulinette-yunohost (2.0~megusta22) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 10:50:53 +0200 + +moulinette-yunohost (2.0~megusta21) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 10:38:27 +0200 + +moulinette-yunohost (2.0~megusta20) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Mon, 19 May 2014 10:34:23 +0200 + +moulinette-yunohost (2.0~megusta19) test; urgency=low + + * Test build: [enh] Move init script in the moulinette-yunohost + package + + -- Adrien Beudin Sun, 18 May 2014 15:15:23 +0200 + +moulinette-yunohost (2.0~megusta18) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sun, 18 May 2014 12:11:17 +0200 + +moulinette-yunohost (2.0~megusta17) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sun, 18 May 2014 11:57:39 +0200 + +moulinette-yunohost (2.0~megusta16) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sun, 18 May 2014 11:14:48 +0200 + +moulinette-yunohost (2.0~megusta15) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 17 May 2014 22:30:18 +0200 + +moulinette-yunohost (2.0~megusta14) test; urgency=low + + * Test build: [fix] Check if firewall.yml is old + + -- Adrien Beudin Sat, 17 May 2014 22:21:48 +0200 + +moulinette-yunohost (2.0~megusta13) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 17 May 2014 22:10:52 +0200 + +moulinette-yunohost (2.0~megusta12) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 17 May 2014 21:58:31 +0200 + +moulinette-yunohost (2.0~megusta11) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 17 May 2014 00:35:13 +0200 + +moulinette-yunohost (2.0~megusta10) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Sat, 17 May 2014 00:16:12 +0200 + +moulinette-yunohost (2.0~megusta9) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Fri, 16 May 2014 23:19:51 +0200 + +moulinette-yunohost (2.0~megusta8) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Fri, 16 May 2014 21:46:50 +0200 + +moulinette-yunohost (2.0~megusta7) test; urgency=low + + * Test build: Remove cache after upgrade + + -- Adrien Beudin Fri, 16 May 2014 20:57:45 +0200 + +moulinette-yunohost (2.0~megusta6) test; urgency=low + + * Test build: Update from git + + -- Adrien Beudin Fri, 16 May 2014 20:05:08 +0200 + +moulinette-yunohost (2.0~megusta5) test; urgency=low + + * Test build: Update init script + + -- Adrien Beudin Fri, 16 May 2014 18:23:14 +0200 + +moulinette-yunohost (2.0~megusta4) test; urgency=low + + * Test build: actionSSSSS map + + -- Adrien Beudin Fri, 16 May 2014 18:05:45 +0200 + +moulinette-yunohost (2.0~megusta3) test; urgency=low + + * Test build: actionSSSSS map + + -- Adrien Beudin Fri, 16 May 2014 17:31:04 +0200 + +moulinette-yunohost (2.0~megusta2) test; urgency=low + + * Test build: Bump version + + -- Adrien Beudin Fri, 16 May 2014 16:28:45 +0200 + +moulinette-yunohost (2.0~megusta1) test; urgency=low + + * Test build: Add moulinette-yunohost package + + -- Adrien Beudin Fri, 16 May 2014 16:05:31 +0200 + +moulinette-yunohost (1.0~megusta1) megusta; urgency=low + + * Init + + -- Adrien Beudin Thu, 15 May 2014 13:16:03 +0200 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..2e7f0a4a3 --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: moulinette-yunohost +Section: net +Priority: extra +Maintainer: Jérôme Lebleu +Build-Depends: debhelper (>=8.0.0) +Standards-Version: 3.9.4 +Homepage: https://yunohost.org/ + +Package: moulinette-yunohost +Architecture: all +Depends: moulinette, + python-psutil, + python-requests, + glances, + python-pip, + rubygems, + pyminiupnpc, + dnsutils +Description: YunoHost Python scripts + Python functions to manage a YunoHost instance + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/debian/install b/debian/install new file mode 100644 index 000000000..5ea885948 --- /dev/null +++ b/debian/install @@ -0,0 +1,6 @@ +bin/* /usr/bin/ +data/actionsmap/* /usr/share/moulinette/actionsmap/ +data/hooks/* /usr/share/yunohost/hooks/ +data/other/* /usr/share/yunohost/yunohost-config/moulinette/ +lib/yunohost/* /usr/lib/moulinette/yunohost/ +locales/* /usr/lib/moulinette/yunohost/locales/ diff --git a/debian/moulinette-yunohost.yunohost-api.init b/debian/moulinette-yunohost.yunohost-api.init new file mode 100755 index 000000000..11c92b747 --- /dev/null +++ b/debian/moulinette-yunohost.yunohost-api.init @@ -0,0 +1,74 @@ +#! /bin/bash +### BEGIN INIT INFO +# Provides: yunohost-api +# Required-Start: $local_fs $remote_fs $network $syslog +# Required-Stop: $local_fs $remote_fs $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start/stop YunoHost API +### END INIT INFO + +DAEMON=/usr/bin/yunohost-api +DAEMON_OPTS="" + +test -x $DAEMON || exit 0 + +. /lib/lsb/init-functions + +logger "YunoHost API: Start script executed" + +case "$1" in + start) + logger "YunoHost API: Starting" + log_daemon_msg "Starting API: YunoHost" + if [[ -f /etc/nginx/conf.d/openresty.conf ]]; + then + DAEMON_OPTS="--no-websocket" + fi + start-stop-daemon --start --background --pidfile /var/run/yunohost-api.pid --make-pidfile \ + --exec /bin/bash -- -c "$DAEMON $DAEMON_OPTS >> /var/log/yunohost.log 2>&1" + log_end_msg $? + ;; + stop) + logger "YunoHost API: Stopping" + log_daemon_msg "Stopping API: YunoHost" + if [ -f /var/run/yunohost-api.pid ]; then + kill `cat /var/run/yunohost-api.pid` > /dev/null 2>&1 + rm -f /var/run/yunohost-api.pid + fi + kill `ps aux | grep 'python /usr/bin/yunohost-api' | grep -v grep | awk '{print $2}'` > /dev/null 2>&1 + kill `ps aux | grep 'yunohost-api' | grep -v grep | grep -v stop | awk '{print $2}'` > /dev/null 2>&1 + log_end_msg 0 + ;; + restart) + logger "YunoHost API: Restarting" + log_daemon_msg "Restarting API: YunoHost" + if [ -f /var/run/yunohost-api.pid ]; then + kill `cat /var/run/yunohost-api.pid` > /dev/null 2>&1 + rm -f /var/run/yunohost-api.pid + fi + kill `ps aux | grep 'python /usr/bin/yunohost-api' | grep -v grep | awk '{print $2}'` > /dev/null 2>&1 + kill `ps aux | grep 'yunohost-api' | grep -v grep | grep -v restart | awk '{print $2}'` > /dev/null 2>&1 + kill `ps aux | grep 'yunohost.tac' | grep -v grep | awk '{print $2}'` > /dev/null 2>&1 + if [[ -f /etc/nginx/conf.d/openresty.conf ]]; + then + DAEMON_OPTS="--no-websocket" + fi + start-stop-daemon --start --background --pidfile /var/run/yunohost-api.pid --make-pidfile \ + --exec /bin/bash -- -c "$DAEMON $DAEMON_OPTS >> /var/log/yunohost.log 2>&1" + log_end_msg $? + ;; + status) + logger "YunoHost API: Running" + log_daemon_msg "YunoHost API: Running" + cat /var/run/yunohost-api.pid > /dev/null 2>&1 + log_end_msg $? + ;; + *) + logger "YunoHost API: Invalid usage" + echo "Usage: /etc/init.d/yunohost-api {start|stop|restart|status}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 000000000..2ad815792 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,56 @@ +#!/bin/bash + +TMP=/usr/share/yunohost/yunohost-config/moulinette + +if [ ! -d /etc/yunohost ]; +then + mkdir -p /etc/yunohost +fi + +# Allow users to access /media directory +if [ ! -d /etc/skel/media ]; +then + mkdir -p /media + ln -s /media /etc/skel/ +fi + +#Firewall +grep -q "UPNP:" /etc/yunohost/firewall.yml > /dev/null 2>&1 +if [[ $? -eq 0 ]] || [ ! -f /etc/yunohost/firewall.yml ]; +then + cp $TMP/firewall.yml /etc/yunohost/ +fi + +# App fetchlist +if [ -f /etc/cron.d/yunohost-applist-yunohost ]; +then + sed -i "s/--no-ldap //g" /etc/cron.d/yunohost-applist-yunohost +fi + +# Service list +if [ ! -f /etc/yunohost/services.yml ]; +then + cp $TMP/services.yml /etc/yunohost/ +fi + +# Stop old API +ps aux | grep "yunohost.tac" | grep -qv grep +if [[ $? -eq 0 ]]; +then + killall twistd +fi + +rm -rf /var/cache/moulinette/* +update-rc.d yunohost-api defaults +service yunohost-api restart + +# Reload SSOwat conf if obsolete +if [ -f /etc/yunohost/installed ]; +then + yunohost firewall upnp | grep -qi "true" + if [[ $? -eq 0 ]]; + then + yunohost firewall upnp enable + fi + yunohost app ssowatconf +fi diff --git a/debian/preinst b/debian/preinst new file mode 100644 index 000000000..43850db1a --- /dev/null +++ b/debian/preinst @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +if [ -f /etc/init.d/yunohost-api ]; then + service yunohost-api stop +# nc -zv 127.0.0.1 6787 < /dev/null 2> /dev/null +# if [[ ! $? -eq 0 ]]; +# then +# exit 1 +# fi +fi diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..cb4a4ccfc --- /dev/null +++ b/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_installinit: + dh_installinit --name=yunohost-api diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/__init__.py b/lib/yunohost/__init__.py similarity index 100% rename from __init__.py rename to lib/yunohost/__init__.py diff --git a/app.py b/lib/yunohost/app.py similarity index 100% rename from app.py rename to lib/yunohost/app.py diff --git a/backup.py b/lib/yunohost/backup.py similarity index 100% rename from backup.py rename to lib/yunohost/backup.py diff --git a/domain.py b/lib/yunohost/domain.py similarity index 100% rename from domain.py rename to lib/yunohost/domain.py diff --git a/dyndns.py b/lib/yunohost/dyndns.py similarity index 100% rename from dyndns.py rename to lib/yunohost/dyndns.py diff --git a/firewall.py b/lib/yunohost/firewall.py similarity index 100% rename from firewall.py rename to lib/yunohost/firewall.py diff --git a/hook.py b/lib/yunohost/hook.py similarity index 100% rename from hook.py rename to lib/yunohost/hook.py diff --git a/monitor.py b/lib/yunohost/monitor.py similarity index 100% rename from monitor.py rename to lib/yunohost/monitor.py diff --git a/service.py b/lib/yunohost/service.py similarity index 100% rename from service.py rename to lib/yunohost/service.py diff --git a/tools.py b/lib/yunohost/tools.py similarity index 100% rename from tools.py rename to lib/yunohost/tools.py diff --git a/user.py b/lib/yunohost/user.py similarity index 100% rename from user.py rename to lib/yunohost/user.py From 645f9440339c20d858a8724eeb2c9366cdf8b1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Sat, 31 Jan 2015 23:49:51 +0100 Subject: [PATCH 09/10] [fix] Install *.py files only and add a gitignore --- .gitignore | 31 +++++++++++++++++++++++++++++++ debian/install | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..e4fc7d9e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +*.py[co] + +# Packages +*.egg +*.egg-info +*.swp +*.swo +dist +build +eggs +parts +bin +cache +var +sdist +develop-eggs +.installed.cfg +log + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg diff --git a/debian/install b/debian/install index 5ea885948..405448e5d 100644 --- a/debian/install +++ b/debian/install @@ -2,5 +2,5 @@ bin/* /usr/bin/ data/actionsmap/* /usr/share/moulinette/actionsmap/ data/hooks/* /usr/share/yunohost/hooks/ data/other/* /usr/share/yunohost/yunohost-config/moulinette/ -lib/yunohost/* /usr/lib/moulinette/yunohost/ +lib/yunohost/*.py /usr/lib/moulinette/yunohost/ locales/* /usr/lib/moulinette/yunohost/locales/ From e93f076856a8292003865be35d4b6a043121be1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= Date: Sun, 1 Feb 2015 01:34:11 +0100 Subject: [PATCH 10/10] [fix] Ooops, so much yolo kills yolo and actionsmap --- data/actionsmap/yunohost.yml | 1207 ++++++++++++++++++++++++++++++++++ 1 file changed, 1207 insertions(+) create mode 100644 data/actionsmap/yunohost.yml diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml new file mode 100644 index 000000000..ca5ce6d3a --- /dev/null +++ b/data/actionsmap/yunohost.yml @@ -0,0 +1,1207 @@ +########################################################################## +# Category/actions/arguments file +# +# +# Except for general_arguments, this file contains 3 levels +# as in this sample command line: +# +# yunohost monitor info --cpu --ram +# ^ ^ ^ ^ +# (script) | category | action | parameters +# +# +# Above example will lead to the function 'monitor_info(args)' +# in the file 'yunohost_monitor.py' with 'cpu' and 'ram' +# stored in an 'args' dictionnary. +# +# Usage: +# You can add a category at the first level, action at the second one, +# and arguments at the third one. +# If a connexion is needed for the action, don't forget to add it to +# the action parameters (ldap, repo, dns or firewall). +# +# Documentation: +# You can see all arguments settings at the argparse documentation: +# http://docs.python.org/dev/library/argparse.html +# #argparse.ArgumentParser.add_argument +# +# Don't forget to turn argument yaml style (setting: value) +# +########################################################################## + +############################# +# Global parameters # +############################# +_global: + configuration: + authenticate: + - api + authenticator: + default: + vendor: ldap + help: admin_password + parameters: + uri: ldap://localhost:389 + base_dn: dc=yunohost,dc=org + user_rdn: cn=admin + ldap-anonymous: + vendor: ldap + parameters: + uri: ldap://localhost:389 + base_dn: dc=yunohost,dc=org + argument_auth: true + lock: true + arguments: + -v: + full: --version + help: Display moulinette version + action: version + version: moulinette %version% + +############################# +# User # +############################# +user: + category_help: Manage users + actions: + + ### user_list() + list: + action_help: List users + api: GET /users + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + --fields: + help: fields to fetch + nargs: "+" + -f: + full: --filter + help: LDAP filter used to search + -l: + full: --limit + help: Maximum number of user fetched + type: int + -o: + full: --offset + help: Starting number for user fetching + type: int + + ### user_create() + create: + action_help: Create user + api: POST /users + configuration: + authenticate: all + arguments: + username: + help: The unique username to create + extra: + pattern: &pattern_username + - !!str ^[a-z0-9_]+$ + - "pattern_username" + -f: + full: --firstname + extra: + ask: ask_firstname + required: True + pattern: &pattern_firstname + - !!str ^([^\W\d_]{2,30}[ ,.'-]{0,3})+$ + - "pattern_firstname" + -l: + full: --lastname + extra: + ask: ask_lastname + required: True + pattern: &pattern_lastname + - !!str ^([^\W\d_]{2,30}[ ,.']{0,3})+$ + - "pattern_lastname" + -m: + full: --mail + help: Main unique email address + extra: + ask: ask_email + required: True + pattern: &pattern_email + - !!str ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,6}$ + - "pattern_email" + -p: + full: --password + help: User password + extra: + password: ask_password + required: True + pattern: &pattern_password + - !!str ^.{3,}$ + - "pattern_password" + + ### user_delete() + delete: + action_help: Delete user + api: DELETE /users/ + configuration: + authenticate: all + arguments: + username: + help: Username to delete + extra: + pattern: *pattern_username + --purge: + action: store_true + + ### user_update() + update: + action_help: Update user informations + api: PUT /users/ + configuration: + authenticate: all + arguments: + username: + help: Username to update + -f: + full: --firstname + extra: + pattern: *pattern_firstname + -l: + full: --lastname + extra: + pattern: *pattern_lastname + -m: + full: --mail + extra: + pattern: *pattern_email + -p: + full: --change-password + help: New password to set + metavar: PASSWORD + extra: + pattern: *pattern_password + --add-mailforward: + help: Mailforward addresses to add + nargs: "*" + metavar: MAIL + extra: + pattern: *pattern_email + --remove-mailforward: + help: Mailforward addresses to remove + nargs: "*" + metavar: MAIL + --add-mailalias: + help: Mail aliases to add + nargs: "*" + metavar: MAIL + extra: + pattern: *pattern_email + --remove-mailalias: + help: Mail aliases to remove + nargs: "*" + metavar: MAIL + + ### user_info() + info: + action_help: Get user information + api: GET /users/ + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + username: + help: Username or email to get information + + +############################# +# Domain # +############################# +domain: + category_help: Manage domains + actions: + + ### domain_list() + list: + action_help: List domains + api: GET /domains + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + -f: + full: --filter + help: LDAP filter used to search + -l: + full: --limit + help: Maximum number of domain fetched + type: int + -o: + full: --offset + help: Starting number for domain fetching + type: int + + ### domain_add() + add: + action_help: Create a custom domain + api: POST /domains + configuration: + authenticate: all + arguments: + domain: + help: Domain name to add + extra: + pattern: &pattern_domain + - !!str ^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+[a-z]{2,}$ + - "pattern_domain" + -d: + full: --dyndns + help: Subscribe to the DynDNS service + action: store_true + + ### domain_remove() + remove: + action_help: Delete domains + api: DELETE /domains/ + configuration: + authenticate: all + arguments: + domain: + help: Domain to delete + extra: + pattern: *pattern_domain + + ### domain_info() +# info: +# action_help: Get domain informations +# api: GET /domains/ +# arguments: +# domain: +# help: "" +# extra: +# pattern: +# - '^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$' +# - "Must be a valid domain name (e.g. my-domain.org)" + + +############################# +# App # +############################# +app: + category_help: Manage apps + actions: + + ### app_fetchlist() + fetchlist: + action_help: Fetch application list from app server + api: PUT /appslists + arguments: + -u: + full: --url + help: URL of remote JSON list (default http://fapp.yunohost.org/app/list/raw) + -n: + full: --name + help: Name of the list (default fapp) + extra: + pattern: &pattern_listname + - !!str ^[a-z0-9_]+$ + - "pattern_listname" + + ### app_listlists() + listlists: + action_help: List fetched lists + api: GET /appslists + + ### app_removelist() + removelist: + action_help: Remove list from the repositories + api: DELETE /appslists + arguments: + name: + help: Name of the list to remove + extra: + ask: ask_list_to_remove + pattern: *pattern_listname + + ### app_list() + list: + action_help: List apps + api: GET /apps + arguments: + -l: + full: --limit + help: Maximum number of app fetched + -o: + full: --offset + help: Starting number for app fetching + -f: + full: --filter + help: Name filter of app_id or app_name + -r: + full: --raw + help: Return the full app_dict + action: store_true + + ### app_info() + info: + action_help: Get app info + api: GET /apps/ + arguments: + app: + help: Specific app ID + -r: + full: --raw + help: Return the full app_dict + action: store_true + + ### app_map() + map: + action_help: List apps by domain + api: GET /appsmap + arguments: + -a: + full: --app + help: Specific app to map + -r: + full: --raw + help: Return complete dict + action: store_true + -u: + full: --user + help: Allowed app map for a user + extra: + pattern: *pattern_username + + ### app_install() + install: + action_help: Install apps + api: POST /apps + configuration: + authenticate: all + authenticator: ldap-anonymous + lock: false + arguments: + app: + help: Name, local path or git URL of the app to install + -l: + full: --label + help: Custom name for the app + -a: + full: --args + help: Serialize arguments for app installation + + ### app_remove() TODO: Write help + remove: + action_help: Remove app + api: DELETE /apps/ + configuration: + authenticate: all + authenticator: ldap-anonymous + lock: false + arguments: + app: + help: App(s) to delete + + ### app_upgrade() + upgrade: + action_help: Upgrade app + api: PUT /upgrade/apps + configuration: + authenticate: all + authenticator: ldap-anonymous + lock: false + arguments: + app: + help: App(s) to upgrade (default all) + nargs: "*" + -u: + full: --url + help: Git url to fetch for upgrade + -f: + full: --file + help: Folder or tarball for upgrade + + ### app_setting() + setting: + action_help: Set ou get an app setting value + api: GET /apps//settings + arguments: + app: + help: App ID + key: + help: Key to get/set + -v: + full: --value + help: Value to set + -d: + full: --delete + help: Delete the key + action: store_true + + ### app_checkport() + checkport: + action_help: Check availability of a local port + api: GET /tools/checkport + arguments: + port: + help: Port to check + extra: + pattern: &pattern_port + - !!str ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$ + - "pattern_port" + + ### app_checkurl() + checkurl: + action_help: Check availability of a web path + api: GET /tools/checkurl + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + url: + help: Url to check + -a: + full: --app + help: Write domain & path to app settings for further checks + + ### app_initdb() + initdb: + action_help: Create database and initialize it with optionnal attached script + api: POST /tools/initdb + arguments: + user: + help: Name of the DB user + -p: + full: --password + help: Password of the DB (generated unless set) + -d: + full: --db + help: DB name (user unless set) + -s: + full: --sql + help: Initial SQL file + + ### app_makedefault() + makedefault: + action_help: Redirect domain root to an app + api: PUT /apps//default + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + app: + help: App name to put on domain root + -d: + full: --domain + help: Specific domain to put app on (the app domain by default) + + ### app_ssowatconf() + ssowatconf: + action_help: Regenerate SSOwat configuration file + api: PUT /ssowatconf + configuration: + authenticate: all + authenticator: ldap-anonymous + + ### app_addaccess() TODO: Write help + addaccess: + action_help: Grant access right to users (everyone by default) + api: PUT /access + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + apps: + nargs: "+" + -u: + full: --users + nargs: "+" + + ### app_removeaccess() TODO: Write help + removeaccess: + action_help: Revoke access right to users (everyone by default) + api: DELETE /access + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + apps: + nargs: "+" + -u: + full: --users + nargs: "+" + + ### app_clearaccess() + clearaccess: + action_help: Reset access rights for the app + api: POST /access + configuration: + authenticate: all + authenticator: ldap-anonymous + arguments: + apps: + nargs: "+" + +############################# +# Backup # +############################# +backup: + category_help: Manage backups + actions: + + ### backup_create() + create: + action_help: Create a backup local archive + api: POST /backup + configuration: + lock: false + arguments: + -n: + full: --name + help: Name of the backup archive + extra: + pattern: &pattern_backup_archive_name + - !!str ^[\w\-\.]{1,30}(? + configuration: + lock: false + arguments: + name: + help: Name of the local backup archive + + +############################# +# Monitor # +############################# +monitor: + category_help: Monitor the server + actions: + + ### monitor_disk() + disk: + action_help: Monitor disk space and usage + api: GET /monitor/disk + arguments: + -f: + full: --filesystem + help: Show filesystem disk space + action: append_const + const: filesystem + dest: units + -t: + full: --io + help: Show I/O throughput + action: append_const + const: io + dest: units + -m: + full: --mountpoint + help: Monitor only the device mounted on MOUNTPOINT + action: store + -H: + full: --human-readable + help: Print sizes in human readable format + action: store_true + + ### monitor_network() + network: + action_help: Monitor network interfaces + api: GET /monitor/network + arguments: + -u: + full: --usage + help: Show interfaces bit rates + action: append_const + const: usage + dest: units + -i: + full: --infos + help: Show network informations + action: append_const + const: infos + dest: units + -H: + full: --human-readable + help: Print sizes in human readable format + action: store_true + + ### monitor_system() + system: + action_help: Monitor system informations and usage + api: GET /monitor/system + arguments: + -m: + full: --memory + help: Show memory usage + action: append_const + const: memory + dest: units + -c: + full: --cpu + help: Show CPU usage and load + action: append_const + const: cpu + dest: units + -p: + full: --process + help: Show processes summary + action: append_const + const: process + dest: units + -u: + full: --uptime + help: Show the system uptime + action: append_const + const: uptime + dest: units + -i: + full: --infos + help: Show system informations + action: append_const + const: infos + dest: units + -H: + full: --human-readable + help: Print sizes in human readable format + action: store_true + + ### monitor_updatestats() + update-stats: + action_help: Update monitoring statistics + api: POST /monitor/stats + arguments: + period: + help: Time period to update + choices: + - day + - week + - month + + ### monitor_showstats() + show-stats: + action_help: Show monitoring statistics + api: GET /monitor/stats + arguments: + period: + help: Time period to show + choices: + - day + - week + - month + + ### monitor_enable() + enable: + action_help: Enable server monitoring + api: PUT /monitor + arguments: + -n: + full: --no-stats + help: Disable monitoring statistics + action: store_true + + ### monitor_disable() + disable: + api: DELETE /monitor + action_help: Disable server monitoring + + +############################# +# Service # +############################# +service: + category_help: Manage services + actions: + + ### service_add() + add: + action_help: Add a service + # api: POST /services + arguments: + name: + help: Service name to add + -s: + full: --status + help: Custom status command + -l: + full: --log + help: Absolute path to log file to display + nargs: "+" + -r: + full: --runlevel + help: Runlevel priority of the service + type: int + + ### service_remove() + remove: + action_help: Remove a service + # api: DELETE /services + arguments: + name: + help: Service name to remove + + ### service_start() + start: + action_help: Start one or more services + api: PUT /services/ + arguments: + names: + help: Service name to start + nargs: "+" + metavar: NAME + + ### service_stop() + stop: + action_help: Stop one or more services + api: DELETE /services/ + arguments: + names: + help: Service name to stop + nargs: "+" + metavar: NAME + + ### service_enable() + enable: + action_help: Enable one or more services + api: PUT /services//enable + arguments: + names: + help: Service name to enable + nargs: "+" + metavar: NAME + + ### service_disable() + disable: + action_help: Disable one or more services + api: DELETE /services//enable + arguments: + names: + help: Service name to disable + nargs: "+" + metavar: NAME + + ### service_status() + status: + action_help: Show status information about one or more services (all by default) + api: + - GET /services + - GET /services/ + arguments: + names: + help: Service name to show + nargs: "*" + metavar: NAME + + ### service_log() + log: + action_help: Log every log files of a service + api: GET /services//log + arguments: + name: + help: Service name to log + -n: + full: --number + help: Number of lines to display + default: 50 + type: int + + +############################# +# Firewall # +############################# +firewall: + category_help: Manage firewall rules + actions: + + ### firewall_list() + list: + action_help: List all firewall rules + api: GET /firewall + arguments: + -r: + full: --raw + help: Return the complete YAML dict + action: store_true + -i: + full: --by-ip-version + help: List rules by IP version + action: store_true + -f: + full: --list-forwarded + help: List forwarded ports with UPnP + action: store_true + + ### firewall_reload() + reload: + action_help: Reload all firewall rules + api: PUT /firewall + + ### firewall_allow() + allow: + action_help: Allow connections on a port + api: POST /firewall/port + arguments: + port: + help: Port or range of ports to open + extra: + pattern: &pattern_port_or_range + - !!str ((^|(?!\A):)([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){1,2}?$ + - "pattern_port_or_range" + -p: + full: --protocol + help: "Protocol type to allow (default: TCP)" + choices: + - TCP + - UDP + - Both + default: TCP + -4: + full: --ipv4-only + help: Only add a rule for IPv4 connections + action: store_true + -6: + full: --ipv6-only + help: Only add a rule for IPv6 connections + action: store_true + --no-upnp: + help: Do not add forwarding of this port with UPnP + action: store_true + --no-reload: + help: Do not reload firewall rules + action: store_true + + + ### firewall_disallow() + disallow: + action_help: Disallow connections on a port + api: DELETE /firewall/port + arguments: + port: + help: Port or range of ports to close + extra: + pattern: *pattern_port_or_range + -p: + full: --protocol + help: "Protocol type to allow (default: TCP)" + choices: + - TCP + - UDP + - Both + default: TCP + -4: + full: --ipv4-only + help: Only remove the rule for IPv4 connections + action: store_true + -6: + full: --ipv6-only + help: Only remove the rule for IPv6 connections + action: store_true + --upnp-only: + help: Only remove forwarding of this port with UPnP + action: store_true + --no-reload: + help: Do not reload firewall rules + action: store_true + + + ### firewall_upnp() + upnp: + action_help: Manage port forwarding using UPnP + api: GET /firewall/upnp + arguments: + action: + choices: + - enable + - disable + - status + - reload + nargs: "?" + default: status + --no-refresh: + help: Do not refresh port forwarding + action: store_true + + ### firewall_stop() + stop: + action_help: Stop iptables and ip6tables + api: DELETE /firewall + + + +############################# +# DynDNS # +############################# +dyndns: + category_help: Subscribe and Update DynDNS Hosts + actions: + + ### dyndns_subscribe() + subscribe: + action_help: Subscribe to a DynDNS service + api: POST /dyndns + arguments: + --subscribe-host: + help: Dynette HTTP API to subscribe to + default: "dyndns.yunohost.org" + -d: + full: --domain + help: Full domain to subscribe with + extra: + pattern: *pattern_domain + -k: + full: --key + help: Public DNS key + + ### dyndns_update() + update: + action_help: Update IP on DynDNS platform + api: PUT /dyndns + arguments: + --dyn-host: + help: Dynette DNS server to inform + default: "dynhost.yunohost.org" + -d: + full: --domain + help: Full domain to subscribe with + extra: + pattern: *pattern_domain + -k: + full: --key + help: Public DNS key + -i: + full: --ip + help: IP address to send + + ### dyndns_installcron() + installcron: + action_help: Install IP update cron + api: POST /dyndns/cron + + ### dyndns_removecron() + removecron: + action_help: Remove IP update cron + api: DELETE /dyndns/cron + + +############################# +# Tools # +############################# +tools: + category_help: Specific tools + actions: + + ### tools_ldapinit() + ldapinit: + action_help: YunoHost LDAP initialization + api: POST /ldap + configuration: + authenticate: all + + ### tools_adminpw() + adminpw: + action_help: Change admin password + api: PUT /adminpw + configuration: + authenticate: all + arguments: + -n: + full: --new-password + extra: + password: ask_new_admin_password + pattern: *pattern_password + required: True + + ### tools_maindomain() + maindomain: + action_help: Main domain change tool + api: PUT /domains/main + configuration: + authenticate: all + arguments: + -o: + full: --old-domain + extra: + pattern: *pattern_domain + -n: + full: --new-domain + extra: + pattern: *pattern_domain + + ### tools_postinstall() + postinstall: + action_help: YunoHost post-install + api: POST /postinstall + configuration: + authenticate: false + lock: false + arguments: + -d: + full: --domain + help: YunoHost main domain + extra: + ask: ask_main_domain + pattern: *pattern_domain + required: True + -p: + full: --password + help: YunoHost admin password + extra: + password: ask_new_admin_password + pattern: *pattern_password + required: True + --ignore-dyndns: + help: Do not subscribe domain to a DynDNS service + action: store_true + + ### tools_update() + update: + action_help: YunoHost update + api: PUT /update + configuration: + lock: false + arguments: + --ignore-apps: + help: Ignore apps cache update and changelog + action: store_true + --ignore-packages: + help: Ignore APT cache update and changelog + action: store_true + + ### tools_upgrade() + upgrade: + action_help: YunoHost upgrade + api: PUT /upgrade + configuration: + authenticate: all + authenticator: ldap-anonymous + lock: false + arguments: + --ignore-apps: + help: Ignore apps upgrade + action: store_true + --ignore-packages: + help: Ignore APT packages upgrade + action: store_true + + +############################# +# Hook # +############################# +hook: + category_help: Manage hooks + actions: + + ### hook_add() + add: + action_help: Store hook script to filesystem + api: PUT /hook + arguments: + app: + help: App to link with + file: + help: Script to add + + ### hook_remove() + remove: + action_help: Remove hook scripts from filesystem + api: DELETE /hook + arguments: + app: + help: Scripts related to app will be removed + + ### hook_list() + list: + action_help: List available hooks for an action + api: GET /hooks/ + arguments: + action: + help: Action name + -l: + full: --list-by + help: Property to list hook by + choices: + - name + - priority + - folder + default: name + -i: + full: --show-info + help: Show hook information + action: store_true + + ### hook_callback() + callback: + action_help: Execute all scripts binded to an action + api: GET /hooks + arguments: + action: + help: Action name + -n: + full: --hooks + help: List of hooks names to execute + nargs: "*" + -a: + full: --args + help: Ordered list of arguments to pass to the script + nargs: "*" + + ### hook_check() + check: + action_help: Parse the script file and get arguments + api: GET /hook/check + arguments: + file: + help: File 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