Introduce a decorator to automatically backup/rollback ldap db during ldap-related migrations

This commit is contained in:
Alexandre Aubin 2021-04-01 19:12:19 +02:00
parent b40f21458f
commit ce946cc0b0
4 changed files with 52 additions and 58 deletions

View file

@ -420,6 +420,10 @@
"migration_description_0018_xtable_to_nftable": "Migrate old network traffic rules to the new nftable system",
"migration_description_0019_extend_permissions_features": "Extend/rework the app permission management system",
"migration_description_0020_ssh_sftp_permissions": "Add SSH and SFTP permissions support",
"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:s}",
"migration_ldap_migration_failed_trying_to_rollback": "Could not migrate... trying to roll back the system.",
"migration_ldap_rollback_success": "System rolled back.",
"migration_0011_create_group": "Creating a group for each user...",
"migration_0011_LDAP_update_failed": "Unable to update LDAP. Error: {error:s}",
"migration_0011_migrate_permission": "Migrating permissions from apps settings to LDAP...",
@ -446,10 +450,6 @@
"migration_0018_failed_to_migrate_iptables_rules": "Failed to migrate legacy iptables rules to nftables: {error}",
"migration_0018_failed_to_reset_legacy_rules": "Failed to reset legacy iptables rules: {error}",
"migration_0019_add_new_attributes_in_ldap": "Add new attributes for permissions in LDAP database",
"migration_0019_backup_before_migration": "Creating a backup of LDAP database and apps settings prior to the actual migration.",
"migration_0019_can_not_backup_before_migration": "The backup of the system could not be completed before the migration failed. Error: {error:s}",
"migration_0019_migration_failed_trying_to_rollback": "Could not migrate... trying to roll back the system.",
"migration_0019_rollback_success": "System rolled back.",
"migration_0019_slapd_config_will_be_overwritten": "It looks like you manually edited the slapd configuration. For this critical migration, YunoHost needs to force the update of the slapd configuration. The original files will be backuped in {conf_backup_folder}.",
"migration_0020_ssh_sftp_permissions": "SSH/SFTP permissions",
"migrations_already_ran": "Those migrations are already done: {ids}",

View file

@ -17,8 +17,6 @@ class MyMigration(Migration):
Add protected attribute in LDAP permission
"""
required = True
def add_new_ldap_attributes(self):
from yunohost.utils.ldap import _get_ldap_interface
@ -78,54 +76,11 @@ class MyMigration(Migration):
ldap.update("cn=%s,ou=permission" % permission, update)
def run(self):
@ldap_migration
def run(self, backup_folder):
# FIXME : what do we really want to do here ...
# Imho we should just force-regen the conf in all case, and maybe
# just display a warning if we detect that the conf was manually modified
# Update LDAP database
self.add_new_ldap_attributes()
# Backup LDAP and the apps settings before to do the migration
logger.info(m18n.n("migration_0019_backup_before_migration"))
try:
backup_folder = "/home/yunohost.backup/premigration/" + time.strftime(
"%Y%m%d-%H%M%S", time.gmtime()
)
os.makedirs(backup_folder, 0o750)
os.system("systemctl stop slapd")
os.system("cp -r --preserve /etc/ldap %s/ldap_config" % backup_folder)
os.system("cp -r --preserve /var/lib/ldap %s/ldap_db" % backup_folder)
os.system(
"cp -r --preserve /etc/yunohost/apps %s/apps_settings" % backup_folder
)
except Exception as e:
raise YunohostError(
"migration_0019_can_not_backup_before_migration", error=e
)
finally:
os.system("systemctl start slapd")
try:
# Update LDAP database
self.add_new_ldap_attributes()
# Migrate old settings
migrate_legacy_permission_settings()
except Exception:
logger.warn(m18n.n("migration_0019_migration_failed_trying_to_rollback"))
os.system("systemctl stop slapd")
os.system(
"rm -r /etc/ldap/slapd.d"
) # To be sure that we don't keep some part of the old config
os.system("cp -r --preserve %s/ldap_config/. /etc/ldap/" % backup_folder)
os.system("cp -r --preserve %s/ldap_db/. /var/lib/ldap/" % backup_folder)
os.system(
"cp -r --preserve %s/apps_settings/. /etc/yunohost/apps/"
% backup_folder
)
os.system("systemctl start slapd")
os.system("rm -r " + backup_folder)
logger.info(m18n.n("migration_0019_rollback_success"))
raise
else:
os.system("rm -r " + backup_folder)
# Migrate old settings
migrate_legacy_permission_settings()

View file

@ -19,9 +19,8 @@ class MyMigration(Migration):
Add new permissions around SSH/SFTP features
"""
required = True
def run(self):
@ldap_migration
def run(self, *args):
logger.info(m18n.n("migration_0020_ssh_sftp_permissions"))
from yunohost.utils.ldap import _get_ldap_interface

View file

@ -1101,6 +1101,7 @@ def _skip_all_migrations():
write_to_yaml(MIGRATIONS_STATE_PATH, new_states)
class Migration(object):
# Those are to be implemented by daughter classes
@ -1125,3 +1126,42 @@ class Migration(object):
@property
def description(self):
return m18n.n("migration_description_%s" % self.id)
def ldap_migration(run):
def func(self):
# Backup LDAP before the migration
logger.info(m18n.n("migration_ldap_backup_before_migration"))
try:
backup_folder = "/home/yunohost.backup/premigration/" + time.strftime(
"%Y%m%d-%H%M%S", time.gmtime()
)
os.makedirs(backup_folder, 0o750)
os.system("systemctl stop slapd")
os.system(f"cp -r --preserve /etc/ldap {backup_folder}/ldap_config")
os.system(f"cp -r --preserve /var/lib/ldap {backup_folder}/ldap_db")
os.system(f"cp -r --preserve /etc/yunohost/apps {backup_folder}/apps_settings")
except Exception as e:
raise YunohostError(
"migration_ldap_can_not_backup_before_migration", error=e
)
finally:
os.system("systemctl start slapd")
try:
run(self, backup_folder)
except Exception:
logger.warn(m18n.n("migration_ldap_migration_failed_trying_to_rollback"))
os.system("systemctl stop slapd")
# To be sure that we don't keep some part of the old config
os.system("rm -r /etc/ldap/slapd.d")
os.system(f"cp -r --preserve {backup_folder}/ldap_config/. /etc/ldap/")
os.system(f"cp -r --preserve {backup_folder}/ldap_db/. /var/lib/ldap/")
os.system(f"cp -r --preserve {backup_folder}/apps_settings/. /etc/yunohost/apps/")
os.system("systemctl start slapd")
os.system(f"rm -r {backup_folder}")
logger.info(m18n.n("migration_ldap_rollback_success"))
raise
else:
os.system(f"rm -r {backup_folder}")