From 731ff6f906bea5ed9543ed49d0180e8360dc7fbd Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 23 Nov 2016 19:36:57 -0500 Subject: [PATCH 1/6] [fix] Refactoring tools_maindomain and disabling removal of main domain to avoid breaking things --- data/actionsmap/yunohost.yml | 7 ++-- locales/en.json | 3 +- src/yunohost/domain.py | 14 ++++++++ src/yunohost/tools.py | 62 ++++++++++++++++-------------------- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 26543721e..91c5b2aad 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -1266,7 +1266,7 @@ tools: ### tools_maindomain() maindomain: - action_help: Main domain change tool + action_help: Check the current main domain, or change it api: - GET /domains/main - PUT /domains/main @@ -1274,12 +1274,9 @@ tools: authenticate: all lock: false arguments: - -o: - full: --old-domain - extra: - pattern: *pattern_domain -n: full: --new-domain + help: Change the current main domain extra: pattern: *pattern_domain diff --git a/locales/en.json b/locales/en.json index e44f87778..6d0ec34bd 100644 --- a/locales/en.json +++ b/locales/en.json @@ -258,5 +258,6 @@ "certmanager_hit_rate_limit" :"Too many certificates already issued for exact set of domains {domain:s} recently. Please try again later. See https://letsencrypt.org/docs/rate-limits/ for more details.", "certmanager_cert_signing_failed" : "Signing the new certificate failed.", "certmanager_no_cert_file" : "Unable to read certificate file for domain {domain:s} (file : {file:s})", - "certmanager_conflicting_nginx_file": "Unable to prepare domain for ACME challenge : the nginx configuration file {filepath:s} is conflicting and should be removed first." + "certmanager_conflicting_nginx_file": "Unable to prepare domain for ACME challenge : the nginx configuration file {filepath:s} is conflicting and should be removed first.", + "domain_cannot_remove_main": "Cannot remove main domain. Set a new main domain first" } diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 415585087..9c1563423 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -113,6 +113,7 @@ def domain_add(auth, domain, dyndns=False): raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) + try: yunohost.certificate._certificate_install_selfsigned([domain], False) @@ -158,6 +159,10 @@ def domain_remove(auth, domain, force=False): if not force and domain not in domain_list(auth)['domains']: raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown')) + # Check domain is not the main domain + if (domain == _get_maindomain()) : + raise MoulinetteError(errno.EINVAL, m18n.n('domain_cannot_remove_main')) + # Check if apps are installed on the domain for app in os.listdir('/etc/yunohost/apps/'): with open('/etc/yunohost/apps/' + app +'/settings.yml') as f: @@ -284,3 +289,12 @@ def get_public_ip(protocol=4): logger.debug('cannot retrieve public IPv%d' % protocol, exc_info=1) raise MoulinetteError(errno.ENETUNREACH, m18n.n('no_internet_connection')) + +def _get_maindomain(): + with open('/etc/yunohost/current_host', 'r') as f: + maindomain = f.readline().rstrip() + return maindomain + +def _set_maindomain(domain): + with open('/etc/yunohost/current_host', 'w') as f: + f.write(domain) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 475bf9b7f..51acc410d 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -39,7 +39,7 @@ import apt.progress from moulinette.core import MoulinetteError, init_authenticator from moulinette.utils.log import getActionLogger from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list -from yunohost.domain import domain_add, domain_list, get_public_ip +from yunohost.domain import domain_add, domain_list, get_public_ip, _get_maindomain, _set_maindomain from yunohost.dyndns import dyndns_subscribe from yunohost.firewall import firewall_upnp from yunohost.service import service_status, service_regen_conf, service_log @@ -127,50 +127,43 @@ def tools_adminpw(auth, new_password): def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): """ - Main domain change tool + Main domain consultaton or change tool Keyword argument: - new_domain - old_domain + new_domain -- The new domain to be set as the main domain """ - if not old_domain: - with open('/etc/yunohost/current_host', 'r') as f: - old_domain = f.readline().rstrip() - - if not new_domain: - return { 'current_main_domain': old_domain } + # If no new domain specified, we return the current main domain if not new_domain: - raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required')) + return { 'current_main_domain': _get_maindomain() } + + # Check domain exists if new_domain not in domain_list(auth)['domains']: - domain_add(auth, new_domain) + raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown')) - os.system('rm /etc/ssl/private/yunohost_key.pem') - os.system('rm /etc/ssl/certs/yunohost_crt.pem') + # Apply changes to ssl certs + ssl_key = "/etc/ssl/private/yunohost_key.pem" + ssl_crt = "/etc/ssl/private/yunohost_crt.pem" + new_ssl_key = "/etc/yunohost/certs/%s/key.pem" % new_domain + new_ssl_crt = "/etc/yunohost/certs/%s/crt.pem" % new_domain - command_list = [ - 'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain, - 'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain, - 'echo %s > /etc/yunohost/current_host' % new_domain, - ] + try: - for command in command_list: - if os.system(command) != 0: - raise MoulinetteError(errno.EPERM, - m18n.n('maindomain_change_failed')) + if os.path.exists(ssl_key) or os.path.lexists(ssl_key) : + os.remove(ssl_key) + if os.path.exists(ssl_crt) or os.path.lexists(ssl_crt) : + os.remove(ssl_crt) - if dyndns and len(new_domain.split('.')) >= 3: - try: - r = requests.get('https://dyndns.yunohost.org/domains') - except requests.ConnectionError: - pass - else: - dyndomains = json.loads(r.text) - dyndomain = '.'.join(new_domain.split('.')[1:]) - if dyndomain in dyndomains: - dyndns_subscribe(domain=new_domain) + os.symlink(new_ssl_key, ssl_key) + os.symlink(new_ssl_crt, ssl_crt) + _set_maindomain(new_domain) + except Exception as e: + print e + raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) + + # Regen configurations try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf() @@ -285,7 +278,8 @@ def tools_postinstall(domain, password, ignore_dyndns=False): m18n.n('yunohost_ca_creation_failed')) # New domain config - tools_maindomain(auth, old_domain='yunohost.org', new_domain=domain, dyndns=dyndns) + domain_add(auth, new_domain, dyndns) + tools_maindomain(auth, old_domain='yunohost.org', new_domain=domain) # Generate SSOwat configuration file app_ssowatconf(auth) From 597da8be465309356b7b16f9766ba8f3449d924c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 25 Nov 2016 03:03:41 +0100 Subject: [PATCH 2/6] Fixing previous commit after postinstall tests --- src/yunohost/tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 51acc410d..8e1603d83 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -125,7 +125,7 @@ def tools_adminpw(auth, new_password): logger.success(m18n.n('admin_password_changed')) -def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): +def tools_maindomain(auth, new_domain=None): """ Main domain consultaton or change tool @@ -278,8 +278,8 @@ def tools_postinstall(domain, password, ignore_dyndns=False): m18n.n('yunohost_ca_creation_failed')) # New domain config - domain_add(auth, new_domain, dyndns) - tools_maindomain(auth, old_domain='yunohost.org', new_domain=domain) + domain_add(auth, domain, dyndns) + tools_maindomain(auth, domain) # Generate SSOwat configuration file app_ssowatconf(auth) From 9c798e5d62c0230823c3b1a317974ce32a79ebd6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Dec 2016 23:40:37 -0500 Subject: [PATCH 3/6] [fix] Fixing message --- src/yunohost/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 8e1603d83..d8b5f7f7e 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -127,7 +127,7 @@ def tools_adminpw(auth, new_password): def tools_maindomain(auth, new_domain=None): """ - Main domain consultaton or change tool + Check the current main domain, or change it Keyword argument: new_domain -- The new domain to be set as the main domain From c468a6975446a839ad1e3c12acbf82494959fae8 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 2 Dec 2016 23:23:06 +0100 Subject: [PATCH 4/6] [mod] pep8 --- src/yunohost/domain.py | 3 ++- src/yunohost/tools.py | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 9c1563423..1aeab33ef 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -160,7 +160,7 @@ def domain_remove(auth, domain, force=False): raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown')) # Check domain is not the main domain - if (domain == _get_maindomain()) : + if domain == _get_maindomain(): raise MoulinetteError(errno.EINVAL, m18n.n('domain_cannot_remove_main')) # Check if apps are installed on the domain @@ -290,6 +290,7 @@ def get_public_ip(protocol=4): raise MoulinetteError(errno.ENETUNREACH, m18n.n('no_internet_connection')) + def _get_maindomain(): with open('/etc/yunohost/current_host', 'r') as f: maindomain = f.readline().rstrip() diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index d8b5f7f7e..2c1c55d77 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -136,7 +136,7 @@ def tools_maindomain(auth, new_domain=None): # If no new domain specified, we return the current main domain if not new_domain: - return { 'current_main_domain': _get_maindomain() } + return {'current_main_domain': _get_maindomain()} # Check domain exists if new_domain not in domain_list(auth)['domains']: @@ -149,7 +149,6 @@ def tools_maindomain(auth, new_domain=None): new_ssl_crt = "/etc/yunohost/certs/%s/crt.pem" % new_domain try: - if os.path.exists(ssl_key) or os.path.lexists(ssl_key) : os.remove(ssl_key) if os.path.exists(ssl_crt) or os.path.lexists(ssl_crt) : From c763b74fea5db85a92daf8c5c5e11598b42abc90 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 2 Dec 2016 23:23:16 +0100 Subject: [PATCH 5/6] [mod] use logger instead of print, a bit better bot not perfect --- src/yunohost/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 2c1c55d77..bd3bb9696 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -159,7 +159,7 @@ def tools_maindomain(auth, new_domain=None): _set_maindomain(new_domain) except Exception as e: - print e + logger.warning("%s" % e, exc_info=1) raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) # Regen configurations From 801ceca32b26d07be9a7e976518538bf4419c6c2 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 2 Dec 2016 23:50:22 +0100 Subject: [PATCH 6/6] [mod] pep8 --- src/yunohost/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index bd3bb9696..7cc221683 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -149,9 +149,9 @@ def tools_maindomain(auth, new_domain=None): new_ssl_crt = "/etc/yunohost/certs/%s/crt.pem" % new_domain try: - if os.path.exists(ssl_key) or os.path.lexists(ssl_key) : + if os.path.exists(ssl_key) or os.path.lexists(ssl_key): os.remove(ssl_key) - if os.path.exists(ssl_crt) or os.path.lexists(ssl_crt) : + if os.path.exists(ssl_crt) or os.path.lexists(ssl_crt): os.remove(ssl_crt) os.symlink(new_ssl_key, ssl_key)