[enh] Add disclaimer and manual or automatic mode on python migrations

This commit is contained in:
ljf 2022-08-07 18:59:39 +02:00 committed by ljf (zamentur)
parent 3b8e49dc64
commit 1d84e07988
2 changed files with 73 additions and 5 deletions

View file

@ -503,10 +503,14 @@
"migration_0023_not_enough_space": "Make sufficient space available in {path} to run the migration.",
"migration_0023_postgresql_11_not_installed": "PostgreSQL was not installed on your system. Nothing to do.",
"migration_0023_postgresql_13_not_installed": "PostgreSQL 11 is installed, but not PostgreSQL 13!? Something weird might have happened on your system :(...",
"migration_0024_rebuild_python_venv_broken_app": "To upgrade your app {app} to bullseye, you probably should force the upgrade of this app thanks to `yunohost app upgrade --force {app}`",
"migration_0024_rebuild_python_venv_disclaimer": "Python applications doesn't support upgrade to bullseye and need an extra steps to rebuild their virtual environement. By running this migration, YunoHost will try to rebuild automaticcaly your Python apps except for : {apps}. For those apps, you should force the upgrade manually by running `yunohost app upgrade -f APP`.",
"migration_0024_rebuild_python_venv_in_progress": "Rebuild the python virtualenv `{venv}`",
"migration_0024_rebuild_python_venv_failed": "Unable to rebuild the python virtual env {venv}, this app is probably broken. If your app is broken, you probably should force the upgrade of this app thanks to `yunohost app upgrade --force APP`",
"migration_description_0021_migrate_to_bullseye": "Upgrade the system to Debian Bullseye and YunoHost 11.x",
"migration_description_0022_php73_to_php74_pools": "Migrate php7.3-fpm 'pool' conf files to php7.4",
"migration_description_0023_postgresql_11_to_13": "Migrate databases from PostgreSQL 11 to 13",
"migration_description_0024_rebuild_python_venv": "Repair python app after bullseye migration",
"migration_ldap_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
"migration_ldap_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error}",
"migration_ldap_migration_failed_trying_to_rollback": "Could not migrate... trying to roll back the system.",

View file

@ -1,12 +1,12 @@
import subprocess
import os
from moulinette import m18n
from moulinette.utils.log import getActionLogger
from moulinette.utils.process import call_async_output
from yunohost.tools import Migration
from yunohost.utils.filesystem import read_file, rm
from yunohost.tools import Migration, tools_migrations_state
from moulinette.utils.filesystem import rm, read_file
logger = getActionLogger("yunohost.migration")
@ -47,8 +47,59 @@ class MyMigration(Migration):
After the update, recreate a python virtual env based on the previously
generated requirements file
"""
ignored_python_apps = [
"calibreweb",
"django-for-runners",
"ffsync",
"jupiterlab",
"librephotos",
"mautrix",
"mediadrop",
"mopidy",
"pgadmin",
"tracim",
"synapse",
"weblate"
]
dependencies = ["migrate_to_bullseye"]
state = None
def is_pending(self):
if not self.state:
self.state = tools_migrations_state()["migrations"].get("0024_rebuild_python_venv", "pending")
return self.state == "pending"
@property
def mode(self):
if not self.is_pending():
return "auto"
if _get_all_venvs("/opt/") + _get_all_venvs("/var/www/"):
return "manual"
else:
return "auto"
@property
def disclaimer(self):
# Avoid having a super long disclaimer to generate if migrations has
# been done
if not self.is_pending():
return None
apps = []
venvs = _get_all_venvs("/opt/") + _get_all_venvs("/var/www/")
for venv in venvs:
if not os.path.isfile(venv + VENV_REQUIREMENTS_SUFFIX):
continue
# Search for ignore apps
for app in self.ignored_python_apps:
if app in venv:
apps.append(app)
return m18n.n("migration_0024_rebuild_python_venv_disclaimer",
apps=", ".join(apps))
def run(self):
@ -57,15 +108,28 @@ class MyMigration(Migration):
if not os.path.isfile(venv + VENV_REQUIREMENTS_SUFFIX):
continue
# Search for ignore apps
ignored_app = None
for app in self.ignored_python_apps:
if app in venv:
ignored_app = app
if ignored_app:
rm(venv + VENV_REQUIREMENTS_SUFFIX)
logger.info(m18n.n("migration_0024_rebuild_python_venv_broken_app", app=ignored_app))
continue
logger.info(m18n.n("migration_0024_rebuild_python_venv_in_progress", venv=venv))
# Recreate the venv
rm(venv, recursive=True)
callbacks = (
lambda l: logger.info("+ " + l.rstrip() + "\r"),
lambda l: logger.debug("+ " + l.rstrip() + "\r"),
lambda l: logger.warning(l.rstrip())
)
call_async_output(["python", "-m", "venv", venv], callbacks)
status = call_async_output([
"{venv}/bin/pip", "install", "-r",
f"{venv}/bin/pip", "install", "-r",
venv + VENV_REQUIREMENTS_SUFFIX], callbacks)
if status != 0:
logger.warning(m18n.n("migration_0024_rebuild_python_venv",