def _test_backup_and_restore_app(mocker, app): # Create a backup of this app with message(mocker, "backup_created"): backup_create(system=None, apps=[app]) archives = backup_list()["archives"] assert len(archives) == 1 archives_info = backup_info(archives[0], with_details=True) assert archives_info["system"] == {} assert len(archives_info["apps"].keys()) == 1 assert app in archives_info["apps"].keys() # Uninstall the app app_remove(app) assert not app_is_installed(app) assert app + ".main" not in user_permission_list()["permissions"] # Restore the app with message(mocker, "restore_complete"): backup_restore(system=None, name=archives[0], apps=[app]) assert app_is_installed(app) # Check permission per_list = user_permission_list()["permissions"] assert app + ".main" in per_list
def uninstall_test_apps_if_needed(): for app in [ "legacy_app", "backup_recommended_app", "wordpress", "permissions_app" ]: if _is_installed(app): app_remove(app)
def test_permission_app_remove(): app_install(os.path.join(get_test_apps_dir(), "permissions_app_ynh"), args="domain=%s&domain_2=%s&path=%s&is_public=0&admin=%s" % (maindomain, other_domains[0], "/urlpermissionapp", "alice"), force=True) app_remove("permissions_app") # Check all permissions for this app got deleted res = user_permission_list(full=True)['permissions'] assert not any(p.startswith("permissions_app.") for p in res.keys())
def test_systemfuckedup_during_app_remove(mocker, secondary_domain): install_break_yo_system(secondary_domain, breakwhat="remove") with pytest.raises(YunohostError): with message(mocker, "app_action_broke_system"): with message(mocker, "app_removed"): app_remove("break_yo_system") assert app_is_not_installed(secondary_domain, "break_yo_system")
def test_legacy_app_install_secondary_domain(secondary_domain): install_legacy_app(secondary_domain, "/legacy") assert app_is_installed(secondary_domain, "legacy_app") assert app_is_exposed_on_http(secondary_domain, "/legacy", "This is a dummy app") app_remove("legacy_app") assert app_is_not_installed(secondary_domain, "legacy_app")
def test_legacy_app_install_private(secondary_domain): install_legacy_app(secondary_domain, "/legacy", public=False) assert app_is_installed(secondary_domain, "legacy_app") assert not app_is_exposed_on_http(secondary_domain, "/legacy", "This is a dummy app") app_remove("legacy_app") assert app_is_not_installed(secondary_domain, "legacy_app")
def test_legacy_app_install_secondary_domain_on_root(secondary_domain): install_legacy_app(secondary_domain, "/") app_map_ = app_map(raw=True) assert secondary_domain in app_map_ assert "/" in app_map_[secondary_domain] assert "id" in app_map_[secondary_domain]["/"] assert app_map_[secondary_domain]["/"]["id"] == "legacy_app" assert app_is_installed(secondary_domain, "legacy_app") assert app_is_exposed_on_http(secondary_domain, "/", "This is a dummy app") app_remove("legacy_app") assert app_is_not_installed(secondary_domain, "legacy_app")
def teardown_function(function): clean_user_groups_permission() global other_domains for domain in other_domains: domain_remove(domain) other_domains = [] _clear_dummy_app_settings() try: app_remove("permissions_app") except: pass try: app_remove("legacy_app") except: pass
def test_legacy_app_failed_remove(mocker, secondary_domain): install_legacy_app(secondary_domain, "/legacy") # The remove script runs with set -eu and attempt to remove this # file without -f, so will fail if it's not there ;) os.remove("/etc/nginx/conf.d/%s.d/%s.conf" % (secondary_domain, "legacy_app")) # TODO / FIXME : can't easily validate that 'app_not_properly_removed' # is triggered for weird reasons ... app_remove("legacy_app") # # Well here, we hit the classical issue where if an app removal script # fails, so far there's no obvious way to make sure that all files related # to this app got removed ... # assert app_is_not_installed(secondary_domain, "legacy")
def test_legacy_app_install_main_domain(): main_domain = _get_maindomain() install_legacy_app(main_domain, "/legacy") app_map_ = app_map(raw=True) assert main_domain in app_map_ assert "/legacy" in app_map_[main_domain] assert "id" in app_map_[main_domain]["/legacy"] assert app_map_[main_domain]["/legacy"]["id"] == "legacy_app" assert app_is_installed(main_domain, "legacy_app") assert app_is_exposed_on_http(main_domain, "/legacy", "This is a dummy app") app_remove("legacy_app") assert app_is_not_installed(main_domain, "legacy_app")
def test_legacy_app_install_multiple_instances(secondary_domain): install_legacy_app(secondary_domain, "/foo") install_legacy_app(secondary_domain, "/bar") assert app_is_installed(secondary_domain, "legacy_app") assert app_is_exposed_on_http(secondary_domain, "/foo", "This is a dummy app") assert app_is_installed(secondary_domain, "legacy_app__2") assert app_is_exposed_on_http(secondary_domain, "/bar", "This is a dummy app") app_remove("legacy_app") assert app_is_not_installed(secondary_domain, "legacy_app") assert app_is_installed(secondary_domain, "legacy_app__2") app_remove("legacy_app__2") assert app_is_not_installed(secondary_domain, "legacy_app") assert app_is_not_installed(secondary_domain, "legacy_app__2")
def clean(): # Make sure we have a ssowat os.system("mkdir -p /etc/ssowat/") app_ssowatconf() test_apps = ["break_yo_system", "legacy_app", "legacy_app__2", "full_domain_app"] for test_app in test_apps: if _is_installed(test_app): app_remove(test_app) for filepath in glob.glob("/etc/nginx/conf.d/*.d/*%s*" % test_app): os.remove(filepath) for folderpath in glob.glob("/etc/yunohost/apps/*%s*" % test_app): shutil.rmtree(folderpath, ignore_errors=True) for folderpath in glob.glob("/var/www/*%s*" % test_app): shutil.rmtree(folderpath, ignore_errors=True) os.system( "bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP DATABASE %s' \"" % test_app ) os.system( "bash -c \"mysql -u root --password=$(cat /etc/yunohost/mysql) 2>/dev/null <<< 'DROP USER %s@localhost'\"" % test_app ) os.system( "systemctl reset-failed nginx" ) # Reset failed quota for service to avoid running into start-limit rate ? os.system("systemctl start nginx") # Clean permissions for permission_name in user_permission_list(short=True)["permissions"]: if any(test_app in permission_name for test_app in test_apps): permission_delete(permission_name, force=True)
def teardown_function(function): try: app_remove("register_url_app") except: pass
def setup_function(function): try: app_remove("register_url_app") except: pass
def teardown_function(function): app_remove("change_url_app")
def domain_remove(operation_logger, domain, remove_apps=False, force=False): """ Delete domains Keyword argument: domain -- Domain to delete remove_apps -- Remove applications installed on the domain force -- Force the domain removal and don't not ask confirmation to remove apps if remove_apps is specified """ from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf, app_info, app_remove from yunohost.utils.ldap import _get_ldap_interface # the 'force' here is related to the exception happening in domain_add ... # we don't want to check the domain exists because the ldap add may have # failed if not force and domain not in domain_list()['domains']: raise YunohostError('domain_name_unknown', domain=domain) # Check domain is not the main domain if domain == _get_maindomain(): other_domains = domain_list()["domains"] other_domains.remove(domain) if other_domains: raise YunohostError( "domain_cannot_remove_main", domain=domain, other_domains="\n * " + ("\n * ".join(other_domains)), ) else: raise YunohostError("domain_cannot_remove_main_add_new_one", domain=domain) # Check if apps are installed on the domain apps_on_that_domain = [] for app in _installed_apps(): settings = _get_app_settings(app) label = app_info(app)["name"] if settings.get("domain") == domain: apps_on_that_domain.append( (app, " - %s \"%s\" on https://%s%s" % (app, label, domain, settings["path"]) if "path" in settings else app)) if apps_on_that_domain: if remove_apps: if msettings.get('interface') == "cli" and not force: answer = msignals.prompt(m18n.n( 'domain_remove_confirm_apps_removal', apps="\n".join([x[1] for x in apps_on_that_domain]), answers='y/N'), color="yellow") if answer.upper() != "Y": raise YunohostError("aborting") for app, _ in apps_on_that_domain: app_remove(app) else: raise YunohostError('domain_uninstall_app_first', apps="\n".join( [x[1] for x in apps_on_that_domain])) operation_logger.start() ldap = _get_ldap_interface() try: ldap.remove("virtualdomain=" + domain + ",ou=domains") except Exception as e: raise YunohostError("domain_deletion_failed", domain=domain, error=e) os.system("rm -rf /etc/yunohost/certs/%s" % domain) # Sometime we have weird issues with the regenconf where some files # appears as manually modified even though they weren't touched ... # There are a few ideas why this happens (like backup/restore nginx # conf ... which we shouldnt do ...). This in turns creates funky # situation where the regenconf may refuse to re-create the conf # (when re-creating a domain..) # # So here we force-clear the has out of the regenconf if it exists. # This is a pretty ad hoc solution and only applied to nginx # because it's one of the major service, but in the long term we # should identify the root of this bug... _force_clear_hashes(["/etc/nginx/conf.d/%s.conf" % domain]) # And in addition we even force-delete the file Otherwise, if the file was # manually modified, it may not get removed by the regenconf which leads to # catastrophic consequences of nginx breaking because it can't load the # cert file which disappeared etc.. if os.path.exists("/etc/nginx/conf.d/%s.conf" % domain): _process_regen_conf("/etc/nginx/conf.d/%s.conf" % domain, new_conf=None, save=True) regen_conf(names=["nginx", "metronome", "dnsmasq", "postfix"]) app_ssowatconf() hook_callback("post_domain_remove", args=[domain]) logger.success(m18n.n("domain_deleted"))