[enh] Split python rebuild migrations

This commit is contained in:
ljf 2022-08-07 16:50:22 +02:00 committed by ljf (zamentur)
parent 51804925f6
commit 3b8e49dc64
2 changed files with 75 additions and 0 deletions

View file

@ -503,6 +503,7 @@
"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_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",

View file

@ -0,0 +1,74 @@
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
logger = getActionLogger("yunohost.migration")
VENV_REQUIREMENTS_SUFFIX = ".requirements_backup_for_bullseye_upgrade.txt"
VENV_IGNORE = "ynh_migration_no_regen"
def _get_all_venvs(dir, level=0, maxlevel=3):
"""
Returns the list of all python virtual env directories recursively
Arguments:
dir - the directory to scan in
maxlevel - the depth of the recursion
level - do not edit this, used as an iterator
"""
# Using os functions instead of glob, because glob doesn't support hidden
# folders, and we need recursion with a fixed depth
result = []
for file in os.listdir(dir):
path = os.path.join(dir, file)
if os.path.isdir(path):
if os.path.isfile(os.path.join(path, VENV_IGNORE)):
continue
activatepath = os.path.join(path, "bin", "activate")
if os.path.isfile(activatepath):
content = read_file(activatepath)
if ("VIRTUAL_ENV" in content) and ("PYTHONHOME" in content):
result.append(path)
continue
if level < maxlevel:
result += _get_all_venvs(path, level=level + 1)
return result
class MyMigration(Migration):
"""
After the update, recreate a python virtual env based on the previously
generated requirements file
"""
dependencies = ["migrate_to_bullseye"]
def run(self):
venvs = _get_all_venvs("/opt/") + _get_all_venvs("/var/www/")
for venv in venvs:
if not os.path.isfile(venv + VENV_REQUIREMENTS_SUFFIX):
continue
# Recreate the venv
rm(venv, recursive=True)
callbacks = (
lambda l: logger.info("+ " + 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",
venv + VENV_REQUIREMENTS_SUFFIX], callbacks)
if status != 0:
logger.warning(m18n.n("migration_0024_rebuild_python_venv",
venv=venv))
else:
rm(venv + VENV_REQUIREMENTS_SUFFIX)