mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Remove deprecated helpers while still supporting them through hacky patching...
This commit is contained in:
parent
f0440fbd6b
commit
ee67ebfd86
6 changed files with 116 additions and 186 deletions
|
@ -738,30 +738,6 @@ app:
|
|||
help: Delete the key
|
||||
action: store_true
|
||||
|
||||
### app_checkport()
|
||||
checkport:
|
||||
action_help: Check availability of a local port
|
||||
api: GET /tools/checkport
|
||||
deprecated: true
|
||||
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
|
||||
deprecated: True
|
||||
arguments:
|
||||
url:
|
||||
help: Url to check
|
||||
-a:
|
||||
full: --app
|
||||
help: Write domain & path to app settings for further checks
|
||||
|
||||
### app_register_url()
|
||||
register-url:
|
||||
|
@ -776,24 +752,6 @@ app:
|
|||
help: The path to be registered (e.g. /coffee)
|
||||
|
||||
|
||||
### app_initdb()
|
||||
initdb:
|
||||
action_help: Create database and initialize it with optionnal attached script
|
||||
api: POST /tools/initdb
|
||||
deprecated: true
|
||||
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_debug()
|
||||
debug:
|
||||
action_help: Display all debug informations for an application
|
||||
|
@ -802,6 +760,7 @@ app:
|
|||
app:
|
||||
help: App name
|
||||
|
||||
|
||||
### app_makedefault()
|
||||
makedefault:
|
||||
action_help: Redirect domain root to an app
|
||||
|
@ -1645,16 +1604,6 @@ tools:
|
|||
help: Show private data (domain, IP)
|
||||
action: store_true
|
||||
|
||||
### tools_port_available()
|
||||
port-available:
|
||||
action_help: Check availability of a local port
|
||||
api: GET /tools/portavailable
|
||||
arguments:
|
||||
port:
|
||||
help: Port to check
|
||||
extra:
|
||||
pattern: *pattern_port
|
||||
|
||||
### tools_shell()
|
||||
shell:
|
||||
action_help: Launch a development shell
|
||||
|
@ -1863,7 +1812,7 @@ log:
|
|||
api: GET /logs
|
||||
arguments:
|
||||
category:
|
||||
help: Log category to display (default operations), could be operation, history, package, system, access, service or app
|
||||
help: Log category to display (default operations), could be operation, history, package, system, access, service or app
|
||||
nargs: "*"
|
||||
-l:
|
||||
full: --limit
|
||||
|
|
|
@ -24,6 +24,31 @@ ynh_find_port () {
|
|||
echo $port
|
||||
}
|
||||
|
||||
# Test if a port is available
|
||||
#
|
||||
# example: ynh_port_available --port=1234 || ynh_die "Port 1234 is needs to be available for this app"
|
||||
#
|
||||
# usage: ynh_find_port --port=XYZ
|
||||
# | arg: -p, --port - port to check
|
||||
#
|
||||
# Requires YunoHost version 3.7.x or higher.
|
||||
ynh_port_available () {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=p
|
||||
declare -Ar args_array=( [p]=port= )
|
||||
local port
|
||||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
|
||||
if netcat -z 127.0.0.1 $port;
|
||||
then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Validate an IP address
|
||||
#
|
||||
# usage: ynh_validate_ip --family=family --ip_address=ip_address
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
"app_id_invalid": "Invalid app id",
|
||||
"app_incompatible": "The app {app} is incompatible with your YunoHost version",
|
||||
"app_install_files_invalid": "Invalid installation files",
|
||||
"app_location_already_used": "The app '{app}' is already installed on that location ({path})",
|
||||
"app_make_default_location_already_used": "Can't make the app '{app}' the default on the domain {domain} is already used by the other app '{other_app}'",
|
||||
"app_location_install_failed": "Unable to install the app in this location because it conflit with the app '{other_app}' already installed on '{other_path}'",
|
||||
"app_location_unavailable": "This url is not available or conflicts with the already installed app(s):\n{apps:s}",
|
||||
"app_manifest_invalid": "Invalid app manifest: {error}",
|
||||
"app_no_upgrade": "No apps to upgrade",
|
||||
|
@ -393,9 +391,6 @@
|
|||
"monitor_stats_no_update": "No monitoring statistics to update",
|
||||
"monitor_stats_period_unavailable": "No available statistics for the period",
|
||||
"mountpoint_unknown": "Unknown mountpoint",
|
||||
"mysql_db_creation_failed": "MySQL database creation failed",
|
||||
"mysql_db_init_failed": "MySQL database init failed",
|
||||
"mysql_db_initialized": "The MySQL database has been initialized",
|
||||
"need_define_permission_before": "You need to redefine the permission using 'yunohost user permission add -u USER' before removing an allowed group",
|
||||
"network_check_mx_ko": "DNS MX record is not set",
|
||||
"network_check_smtp_ko": "Outbound mail (SMTP port 25) seems to be blocked by your network",
|
||||
|
@ -444,8 +439,6 @@
|
|||
"permission_update_nothing_to_do": "No permissions to update",
|
||||
"port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections",
|
||||
"port_already_opened": "Port {port:d} is already opened for {ip_version:s} connections",
|
||||
"port_available": "Port {port:d} is available",
|
||||
"port_unavailable": "Port {port:d} is not available",
|
||||
"recommend_to_add_first_user": "The post-install is finished but YunoHost needs at least one user to work correctly, you should add one using 'yunohost user create $username' or the admin interface.",
|
||||
"remove_main_permission_not_allowed": "Removing the main permission is not allowed",
|
||||
"remove_user_of_group_not_allowed": "You are not allowed to remove the user {user:s} in the group {group:s}",
|
||||
|
|
|
@ -41,7 +41,7 @@ from datetime import datetime
|
|||
|
||||
from moulinette import msignals, m18n, msettings
|
||||
from moulinette.utils.log import getActionLogger
|
||||
from moulinette.utils.filesystem import read_json, read_toml
|
||||
from moulinette.utils.filesystem import read_file, read_json, read_toml, write_to_file
|
||||
|
||||
from yunohost.service import service_log, service_status, _run_service_command
|
||||
from yunohost.utils import packages
|
||||
|
@ -315,6 +315,7 @@ def app_list(filter=None, raw=False, installed=False, with_backup=False):
|
|||
|
||||
# dirty: we used to have manifest containing multi_instance value in form of a string
|
||||
# but we've switched to bool, this line ensure retrocompatibility
|
||||
|
||||
app_info_dict["manifest"]["multi_instance"] = is_true(app_info_dict["manifest"].get("multi_instance", False))
|
||||
|
||||
list_dict[app_id] = app_info_dict
|
||||
|
@ -667,6 +668,9 @@ def app_upgrade(app=[], url=None, file=None):
|
|||
operation_logger = OperationLogger('app_upgrade', related_to, env=env_dict)
|
||||
operation_logger.start()
|
||||
|
||||
# Attempt to patch legacy helpers ...
|
||||
_patch_legacy_helpers(extracted_app_folder)
|
||||
|
||||
# Apply dirty patch to make php5 apps compatible with php7
|
||||
_patch_php5(extracted_app_folder)
|
||||
|
||||
|
@ -854,6 +858,9 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
|||
app_settings['install_time'] = status['installed_at']
|
||||
_set_app_settings(app_instance_name, app_settings)
|
||||
|
||||
# Attempt to patch legacy helpers ...
|
||||
_patch_legacy_helpers(extracted_app_folder)
|
||||
|
||||
# Apply dirty patch to make php5 apps compatible with php7
|
||||
_patch_php5(extracted_app_folder)
|
||||
|
||||
|
@ -996,6 +1003,9 @@ def app_remove(operation_logger, app):
|
|||
except:
|
||||
pass
|
||||
|
||||
# Attempt to patch legacy helpers ...
|
||||
_patch_legacy_helpers(app_setting_path)
|
||||
|
||||
# Apply dirty patch to make php5 apps compatible with php7 (e.g. the remove
|
||||
# script might date back from jessie install)
|
||||
_patch_php5(app_setting_path)
|
||||
|
@ -1197,24 +1207,6 @@ def app_setting(app, key, value=None, delete=False):
|
|||
_set_app_settings(app, app_settings)
|
||||
|
||||
|
||||
def app_checkport(port):
|
||||
"""
|
||||
Check availability of a local port
|
||||
|
||||
Keyword argument:
|
||||
port -- Port to check
|
||||
|
||||
"""
|
||||
|
||||
# This import cannot be moved on top of file because it create a recursive
|
||||
# import...
|
||||
from yunohost.tools import tools_port_available
|
||||
if tools_port_available(port):
|
||||
logger.success(m18n.n('port_available', port=int(port)))
|
||||
else:
|
||||
raise YunohostError('port_unavailable', port=int(port))
|
||||
|
||||
|
||||
def app_register_url(app, domain, path):
|
||||
"""
|
||||
Book/register a web path for a given app
|
||||
|
@ -1258,93 +1250,6 @@ def app_register_url(app, domain, path):
|
|||
app_setting(app, 'path', value=path)
|
||||
|
||||
|
||||
def app_checkurl(url, app=None):
|
||||
"""
|
||||
Check availability of a web path
|
||||
|
||||
Keyword argument:
|
||||
url -- Url to check
|
||||
app -- Write domain & path to app settings for further checks
|
||||
|
||||
"""
|
||||
|
||||
logger.error("Packagers /!\\ : 'app checkurl' is deprecated ! Please use the helper 'ynh_webpath_register' instead !")
|
||||
|
||||
from yunohost.domain import domain_list, _normalize_domain_path
|
||||
|
||||
if "https://" == url[:8]:
|
||||
url = url[8:]
|
||||
elif "http://" == url[:7]:
|
||||
url = url[7:]
|
||||
|
||||
if url[-1:] != '/':
|
||||
url = url + '/'
|
||||
|
||||
domain = url[:url.index('/')]
|
||||
path = url[url.index('/'):]
|
||||
installed = False
|
||||
|
||||
domain, path = _normalize_domain_path(domain, path)
|
||||
|
||||
apps_map = app_map(raw=True)
|
||||
|
||||
if domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
if domain in apps_map:
|
||||
# Loop through apps
|
||||
for p, a in apps_map[domain].items():
|
||||
# Skip requested app checking
|
||||
if app is not None and a['id'] == app:
|
||||
installed = True
|
||||
continue
|
||||
if path == p:
|
||||
raise YunohostError('app_location_already_used', app=a["id"], path=path)
|
||||
# can't install "/a/b/" if "/a/" exists
|
||||
elif path.startswith(p) or p.startswith(path):
|
||||
raise YunohostError('app_location_install_failed', other_path=p, other_app=a['id'])
|
||||
|
||||
if app is not None and not installed:
|
||||
app_setting(app, 'domain', value=domain)
|
||||
app_setting(app, 'path', value=path)
|
||||
|
||||
|
||||
def app_initdb(user, password=None, db=None, sql=None):
|
||||
"""
|
||||
Create database and initialize it with optionnal attached script
|
||||
|
||||
Keyword argument:
|
||||
db -- DB name (user unless set)
|
||||
user -- Name of the DB user
|
||||
password -- Password of the DB (generated unless set)
|
||||
sql -- Initial SQL file
|
||||
|
||||
"""
|
||||
|
||||
logger.error("Packagers /!\\ : 'app initdb' is deprecated ! Please use the helper 'ynh_mysql_setup_db' instead !")
|
||||
|
||||
if db is None:
|
||||
db = user
|
||||
|
||||
return_pwd = False
|
||||
if password is None:
|
||||
password = random_password(12)
|
||||
return_pwd = True
|
||||
|
||||
mysql_root_pwd = open('/etc/yunohost/mysql').read().rstrip()
|
||||
mysql_command = 'mysql -u root -p%s -e "CREATE DATABASE %s ; GRANT ALL PRIVILEGES ON %s.* TO \'%s\'@localhost IDENTIFIED BY \'%s\';"' % (mysql_root_pwd, db, db, user, password)
|
||||
if os.system(mysql_command) != 0:
|
||||
raise YunohostError('mysql_db_creation_failed')
|
||||
if sql is not None:
|
||||
if os.system('mysql -u %s -p%s %s < %s' % (user, password, db, sql)) != 0:
|
||||
raise YunohostError('mysql_db_init_failed')
|
||||
|
||||
if return_pwd:
|
||||
return password
|
||||
|
||||
logger.success(m18n.n('mysql_db_initialized'))
|
||||
|
||||
|
||||
def app_ssowatconf():
|
||||
"""
|
||||
Regenerate SSOwat configuration file
|
||||
|
@ -2951,3 +2856,77 @@ def _patch_php5(app_folder):
|
|||
"-e 's@php5@php7.0@g' " \
|
||||
"%s" % filename
|
||||
os.system(c)
|
||||
|
||||
def _patch_legacy_helpers(app_folder):
|
||||
|
||||
files_to_patch = []
|
||||
files_to_patch.extend(glob.glob("%s/scripts/*" % app_folder))
|
||||
files_to_patch.extend(glob.glob("%s/scripts/.*" % app_folder))
|
||||
|
||||
stuff_to_replace = {
|
||||
# Replace
|
||||
# sudo yunohost app initdb $db_user -p $db_pwd
|
||||
# by
|
||||
# ynh_mysql_setup_db --db_user=$db_user --db_name=$db_user --db_pwd=$db_pwd
|
||||
"yunohost app initdb": (
|
||||
r"(sudo )?yunohost app initdb \"?(\$\{?\w+\}?)\"?\s+-p\s\"?(\$\{?\w+\}?)\"?",
|
||||
r"ynh_mysql_setup_db --db_user=\2 --db_name=\2 --db_pwd=\3"),
|
||||
# Replace
|
||||
# sudo yunohost app checkport whaterver
|
||||
# by
|
||||
# ynh_port_available whatever
|
||||
"yunohost app checkport": (
|
||||
r"(sudo )?yunohost app checkport",
|
||||
r"ynh_port_available"),
|
||||
# We can't migrate easily port-available
|
||||
# .. but at the time of writing this code, only two non-working apps are using it.
|
||||
"yunohost tools port-available": (None, None),
|
||||
# Replace
|
||||
# yunohost app checkurl "${domain}${path_url}" -a "${app}"
|
||||
# by
|
||||
# ynh_webpath_register --app=${app} --domain=${domain} --path_url=${path_url}
|
||||
"yunohost app checkurl": (
|
||||
r"(sudo )?yunohost app checkurl \"?(\$\{?\w+\}?)\/?(\$\{?\w+\}?)\"?\s+-a\s\"?(\$\{?\w+\}?)\"?",
|
||||
r"ynh_webpath_register --app=\4 --domain=\2 --path_url=\3"),
|
||||
}
|
||||
|
||||
stuff_to_replace_compiled = {h: (re.compile(r[0]), r[1]) if r[0] else (None,None) for h, r in stuff_to_replace.items()}
|
||||
|
||||
for filename in files_to_patch:
|
||||
|
||||
# Ignore non-regular files
|
||||
if not os.path.isfile(filename):
|
||||
continue
|
||||
|
||||
content = read_file(filename)
|
||||
replaced_stuff = False
|
||||
|
||||
for helper, regexes in stuff_to_replace_compiled.items():
|
||||
pattern, replace = regexes
|
||||
# If helper is used, attempt to patch the file
|
||||
if helper in content and pattern != "":
|
||||
try:
|
||||
content = pattern.sub(replace, content)
|
||||
replaced_stuff = True
|
||||
except Exception as e:
|
||||
import pdb; pdb.set_trace()
|
||||
|
||||
# If we couldn't patch the deprecated helper, abort the install or whichever step is performed
|
||||
if helper in content:
|
||||
raise YunohostError("This app is likely pretty old and uses deprecated / outdated helpers that can't be migrated easily. It can't be installed anymore.")
|
||||
|
||||
if replaced_stuff:
|
||||
|
||||
# Check the app do load the helper
|
||||
# If it doesn't, add the instruction ourselve (making sure it's after the #!/bin/bash if it's there...
|
||||
if filename.split("/")[-1] in ["install", "remove", "upgrade", "backup", "restore"]:
|
||||
source_helpers = "source /usr/share/yunohost/helpers"
|
||||
if source_helpers not in content:
|
||||
content.replace("#!/bin/bash", "#!/bin/bash\n"+source_helpers)
|
||||
if source_helpers not in content:
|
||||
content = source_helpers + "\n" + content
|
||||
|
||||
# Actually write the new content in the file
|
||||
write_to_file(filename, content)
|
||||
# And complain about those damn deprecated helpers
|
||||
logger.error("/!\ Packagers ! This app uses a very old deprecated helpers ... Yunohost automatically patched the helpers to use the new recommended practice, but please do consider fixing the upstream code right now ...")
|
||||
|
|
|
@ -43,7 +43,7 @@ from moulinette.utils.log import getActionLogger
|
|||
from moulinette.utils.filesystem import read_file, mkdir
|
||||
|
||||
from yunohost.app import (
|
||||
app_info, _is_installed, _parse_app_instance_name, _patch_php5
|
||||
app_info, _is_installed, _parse_app_instance_name, _patch_php5, _patch_legacy_helpers
|
||||
)
|
||||
from yunohost.hook import (
|
||||
hook_list, hook_info, hook_callback, hook_exec, CUSTOM_HOOK_FOLDER
|
||||
|
@ -1335,6 +1335,9 @@ class RestoreManager():
|
|||
app_settings_in_archive = os.path.join(app_dir_in_archive, 'settings')
|
||||
app_scripts_in_archive = os.path.join(app_settings_in_archive, 'scripts')
|
||||
|
||||
# Attempt to patch legacy helpers...
|
||||
_patch_legacy_helpers(app_settings_in_archive)
|
||||
|
||||
# Apply dirty patch to make php5 apps compatible with php7
|
||||
_patch_php5(app_settings_in_archive)
|
||||
|
||||
|
|
|
@ -907,25 +907,6 @@ def _check_if_vulnerable_to_meltdown():
|
|||
return CVEs[0]["VULNERABLE"]
|
||||
|
||||
|
||||
def tools_port_available(port):
|
||||
"""
|
||||
Check availability of a local port
|
||||
|
||||
Keyword argument:
|
||||
port -- Port to check
|
||||
|
||||
"""
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.settimeout(1)
|
||||
s.connect(("localhost", int(port)))
|
||||
s.close()
|
||||
except socket.error:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
@is_unit_operation()
|
||||
def tools_shutdown(operation_logger, force=False):
|
||||
shutdown = force
|
||||
|
|
Loading…
Add table
Reference in a new issue