mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #864 from YunoHost/abort_if_up_to_date_manifest
Implement `upgrade_only_if_version_changes` in manifest
This commit is contained in:
commit
b869f3a7d7
3 changed files with 104 additions and 7 deletions
|
@ -660,6 +660,10 @@ app:
|
||||||
-f:
|
-f:
|
||||||
full: --file
|
full: --file
|
||||||
help: Folder or tarball for upgrade
|
help: Folder or tarball for upgrade
|
||||||
|
-F:
|
||||||
|
full: --force
|
||||||
|
help: Force the update, even though the app is up to date
|
||||||
|
action: store_true
|
||||||
|
|
||||||
### app_change_url()
|
### app_change_url()
|
||||||
change-url:
|
change-url:
|
||||||
|
|
|
@ -436,9 +436,8 @@ ynh_app_upstream_version () {
|
||||||
local manifest
|
local manifest
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
manifest="${manifest:-../manifest.json}"
|
|
||||||
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
version_key=$YNH_APP_MANIFEST_VERSION
|
||||||
echo "${version_key/~ynh*/}"
|
echo "${version_key/~ynh*/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,9 +460,8 @@ ynh_app_package_version () {
|
||||||
local manifest
|
local manifest
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
manifest="${manifest:-../manifest.json}"
|
|
||||||
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
version_key=$YNH_APP_MANIFEST_VERSION
|
||||||
echo "${version_key/*~ynh/}"
|
echo "${version_key/*~ynh/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,3 +514,49 @@ ynh_check_app_version_changed () {
|
||||||
fi
|
fi
|
||||||
echo $return_value
|
echo $return_value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Compare the current package version against another version given as an argument.
|
||||||
|
# This is really useful when we need to do some actions only for some old package versions.
|
||||||
|
#
|
||||||
|
# example: ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1
|
||||||
|
# This example will check if the installed version is lower than (lt) the version 2.3.2~ynh1
|
||||||
|
#
|
||||||
|
# Generally you might probably use it as follow in the upgrade script
|
||||||
|
#
|
||||||
|
# if ynh_compare_current_package_version --comparaison lt --version 2.3.2~ynh1
|
||||||
|
# then
|
||||||
|
# # Do something that is needed for the package version older than 2.3.2~ynh1
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# usage: ynh_compare_current_package_version --comparison lt|le|eq|ne|ge|gt
|
||||||
|
# | arg: --comparison - Comparison type. Could be : lt (lower than), le (lower or equal),
|
||||||
|
# | eq (equal), ne (not equal), ge (greater or equal), gt (greater than)
|
||||||
|
# | arg: --version - The version to compare. Need to be a version in the yunohost package version type (like 2.3.1~ynh4)
|
||||||
|
#
|
||||||
|
# Return 0 if the evaluation is true. 1 if false.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.8.0 or higher.
|
||||||
|
ynh_compare_current_package_version() {
|
||||||
|
local legacy_args=cv
|
||||||
|
declare -Ar args_array=( [c]=comparison= [v]=version= )
|
||||||
|
local version
|
||||||
|
local comparison
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
local current_version=$YNH_APP_CURRENT_VERSION
|
||||||
|
|
||||||
|
# Check the syntax of the versions
|
||||||
|
if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]]
|
||||||
|
then
|
||||||
|
ynh_die "Invalid argument for version."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check validity of the comparator
|
||||||
|
if [[ ! $comparison =~ (lt|le|eq|ne|ge|gt) ]]; then
|
||||||
|
ynh_die "Invialid comparator must be : lt, le, eq, ne, ge, gt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Return the return value of dpkg --compare-versions
|
||||||
|
dpkg --compare-versions $current_version $comparison $version
|
||||||
|
}
|
||||||
|
|
|
@ -184,11 +184,21 @@ def app_info(app, full=False):
|
||||||
|
|
||||||
|
|
||||||
def _app_upgradable(app_infos):
|
def _app_upgradable(app_infos):
|
||||||
|
from packaging import version
|
||||||
|
|
||||||
# Determine upgradability
|
# Determine upgradability
|
||||||
# In case there is neither update_time nor install_time, we assume the app can/has to be upgraded
|
# In case there is neither update_time nor install_time, we assume the app can/has to be upgraded
|
||||||
|
|
||||||
if not app_infos.get("from_catalog", None):
|
# Firstly use the version to know if an upgrade is available
|
||||||
|
app_is_in_catalog = bool(app_infos.get("from_catalog"))
|
||||||
|
installed_version = version.parse(app_infos.get("version", "0~ynh0"))
|
||||||
|
version_in_catalog = version.parse(app_infos.get("from_catalog", {}).get("manifest", {}).get("version", "0~ynh0"))
|
||||||
|
|
||||||
|
if app_is_in_catalog and '~ynh' in str(installed_version) and '~ynh' in str(version_in_catalog):
|
||||||
|
if installed_version < version_in_catalog:
|
||||||
|
return "yes"
|
||||||
|
|
||||||
|
if not app_is_in_catalog:
|
||||||
return "url_required"
|
return "url_required"
|
||||||
if not app_infos["from_catalog"].get("lastUpdate") or not app_infos["from_catalog"].get("git"):
|
if not app_infos["from_catalog"].get("lastUpdate") or not app_infos["from_catalog"].get("git"):
|
||||||
return "url_required"
|
return "url_required"
|
||||||
|
@ -378,6 +388,7 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
env_dict["YNH_APP_ID"] = app_id
|
env_dict["YNH_APP_ID"] = app_id
|
||||||
env_dict["YNH_APP_INSTANCE_NAME"] = app
|
env_dict["YNH_APP_INSTANCE_NAME"] = app
|
||||||
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
||||||
|
env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?")
|
||||||
|
|
||||||
env_dict["YNH_APP_OLD_DOMAIN"] = old_domain
|
env_dict["YNH_APP_OLD_DOMAIN"] = old_domain
|
||||||
env_dict["YNH_APP_OLD_PATH"] = old_path
|
env_dict["YNH_APP_OLD_PATH"] = old_path
|
||||||
|
@ -441,7 +452,7 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
hook_callback('post_app_change_url', args=args_list, env=env_dict)
|
hook_callback('post_app_change_url', args=args_list, env=env_dict)
|
||||||
|
|
||||||
|
|
||||||
def app_upgrade(app=[], url=None, file=None):
|
def app_upgrade(app=[], url=None, file=None, force=False):
|
||||||
"""
|
"""
|
||||||
Upgrade app
|
Upgrade app
|
||||||
|
|
||||||
|
@ -451,6 +462,7 @@ def app_upgrade(app=[], url=None, file=None):
|
||||||
url -- Git url to fetch for upgrade
|
url -- Git url to fetch for upgrade
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from packaging import version
|
||||||
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
|
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
|
||||||
from yunohost.permission import permission_sync_to_user
|
from yunohost.permission import permission_sync_to_user
|
||||||
from yunohost.regenconf import manually_modified_files
|
from yunohost.regenconf import manually_modified_files
|
||||||
|
@ -491,12 +503,41 @@ def app_upgrade(app=[], url=None, file=None):
|
||||||
elif app_dict["upgradable"] == "url_required":
|
elif app_dict["upgradable"] == "url_required":
|
||||||
logger.warning(m18n.n('custom_app_url_required', app=app_instance_name))
|
logger.warning(m18n.n('custom_app_url_required', app=app_instance_name))
|
||||||
continue
|
continue
|
||||||
elif app_dict["upgradable"] == "yes":
|
elif app_dict["upgradable"] == "yes" or force:
|
||||||
manifest, extracted_app_folder = _fetch_app_from_git(app_instance_name)
|
manifest, extracted_app_folder = _fetch_app_from_git(app_instance_name)
|
||||||
else:
|
else:
|
||||||
logger.success(m18n.n('app_already_up_to_date', app=app_instance_name))
|
logger.success(m18n.n('app_already_up_to_date', app=app_instance_name))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Manage upgrade type and avoid any upgrade if there is nothing to do
|
||||||
|
upgrade_type = "UNKNOWN"
|
||||||
|
# Get current_version and new version
|
||||||
|
app_new_version = version.parse(manifest.get("version", "?"))
|
||||||
|
app_current_version = version.parse(app_dict.get("version", "?"))
|
||||||
|
if "~ynh" in str(app_current_version) and "~ynh" in str(app_new_version):
|
||||||
|
if app_current_version >= app_new_version and not force:
|
||||||
|
# In case of upgrade from file or custom repository
|
||||||
|
# No new version available
|
||||||
|
logger.success(m18n.n('app_already_up_to_date', app=app_instance_name))
|
||||||
|
# Save update time
|
||||||
|
now = int(time.time())
|
||||||
|
app_setting(app_instance_name, 'update_time', now)
|
||||||
|
app_setting(app_instance_name, 'current_revision', manifest.get('remote', {}).get('revision', "?"))
|
||||||
|
continue
|
||||||
|
elif app_current_version > app_new_version:
|
||||||
|
upgrade_type = "DOWNGRADE_FORCED"
|
||||||
|
elif app_current_version == app_new_version:
|
||||||
|
upgrade_type = "UPGRADE_FORCED"
|
||||||
|
else:
|
||||||
|
app_current_version_upstream, app_current_version_pkg = str(app_current_version).split("~ynh")
|
||||||
|
app_new_version_upstream, app_new_version_pkg = str(app_new_version).split("~ynh")
|
||||||
|
if app_current_version_upstream == app_new_version_upstream:
|
||||||
|
upgrade_type = "UPGRADE_PACKAGE"
|
||||||
|
elif app_current_version_pkg == app_new_version_pkg:
|
||||||
|
upgrade_type = "UPGRADE_APP"
|
||||||
|
else:
|
||||||
|
upgrade_type = "UPGRADE_FULL"
|
||||||
|
|
||||||
# Check requirements
|
# Check requirements
|
||||||
_check_manifest_requirements(manifest, app_instance_name=app_instance_name)
|
_check_manifest_requirements(manifest, app_instance_name=app_instance_name)
|
||||||
_assert_system_is_sane_for_app(manifest, "pre")
|
_assert_system_is_sane_for_app(manifest, "pre")
|
||||||
|
@ -515,6 +556,9 @@ def app_upgrade(app=[], url=None, file=None):
|
||||||
env_dict["YNH_APP_ID"] = app_id
|
env_dict["YNH_APP_ID"] = app_id
|
||||||
env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
||||||
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
||||||
|
env_dict["YNH_APP_UPGRADE_TYPE"] = upgrade_type
|
||||||
|
env_dict["YNH_APP_MANIFEST_VERSION"] = str(app_new_version)
|
||||||
|
env_dict["YNH_APP_CURRENT_VERSION"] = str(app_current_version)
|
||||||
|
|
||||||
# We'll check that the app didn't brutally edit some system configuration
|
# We'll check that the app didn't brutally edit some system configuration
|
||||||
manually_modified_files_before_install = manually_modified_files()
|
manually_modified_files_before_install = manually_modified_files()
|
||||||
|
@ -745,6 +789,9 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
env_dict["YNH_APP_ID"] = app_id
|
env_dict["YNH_APP_ID"] = app_id
|
||||||
env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
env_dict["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
||||||
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(instance_number)
|
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(instance_number)
|
||||||
|
env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?")
|
||||||
|
|
||||||
|
# Start register change on system
|
||||||
operation_logger.extra.update({'env': env_dict})
|
operation_logger.extra.update({'env': env_dict})
|
||||||
|
|
||||||
# We'll check that the app didn't brutally edit some system configuration
|
# We'll check that the app didn't brutally edit some system configuration
|
||||||
|
@ -854,6 +901,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
env_dict_remove["YNH_APP_ID"] = app_id
|
env_dict_remove["YNH_APP_ID"] = app_id
|
||||||
env_dict_remove["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
env_dict_remove["YNH_APP_INSTANCE_NAME"] = app_instance_name
|
||||||
env_dict_remove["YNH_APP_INSTANCE_NUMBER"] = str(instance_number)
|
env_dict_remove["YNH_APP_INSTANCE_NUMBER"] = str(instance_number)
|
||||||
|
env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?")
|
||||||
|
|
||||||
# Execute remove script
|
# Execute remove script
|
||||||
operation_logger_remove = OperationLogger('remove_on_failed_install',
|
operation_logger_remove = OperationLogger('remove_on_failed_install',
|
||||||
|
@ -1050,6 +1098,7 @@ def app_remove(operation_logger, app):
|
||||||
env_dict["YNH_APP_ID"] = app_id
|
env_dict["YNH_APP_ID"] = app_id
|
||||||
env_dict["YNH_APP_INSTANCE_NAME"] = app
|
env_dict["YNH_APP_INSTANCE_NAME"] = app
|
||||||
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
|
||||||
|
env_dict["YNH_APP_MANIFEST_VERSION"] = manifest.get("version", "?")
|
||||||
operation_logger.extra.update({'env': env_dict})
|
operation_logger.extra.update({'env': env_dict})
|
||||||
operation_logger.flush()
|
operation_logger.flush()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue