blob: 04a3bb36b887f72c7c6fe905d8bf412c0d6dffd8 [file] [log] [blame]
Mitja Nikolaus6820ad02018-10-05 09:58:18 +02001# -*- coding: utf-8 -*-
2
3"""Migrations to update the path where logfiles are stored."""
4# pylint: disable=invalid-name
5
6import logging
7import os
8import shutil
9
10from django.db import migrations
11from django.conf import settings
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020012from django.core.files.storage import default_storage
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020013
14from crashreports.models import LogFile, crashreport_file_name
15
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010016LOGGER = logging.getLogger(__name__)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020017
18
19def migrate_logfiles(apps, schema_editor):
20 """Migrate the logfiles and update the logfile paths in the database."""
21 # pylint: disable=unused-argument
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020022 crashreport_uploads_dir = "crashreport_uploads"
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020023
24 if not LogFile.objects.filter(
25 logfile__startswith=crashreport_uploads_dir
26 ).exists():
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010027 LOGGER.info(
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020028 "No old logfile path found. Assuming this is a new installation "
29 "and the migration does not need to be applied."
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020030 )
31 return
32
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020033 crashreport_uploads_legacy_dir = crashreport_uploads_dir + "_legacy"
34 assert not os.path.isdir(crashreport_uploads_legacy_dir), (
35 "Existing crashreport_uploads_legacy directory found. Remove this"
36 "directory in order to run this migration."
37 )
38
39 if os.path.isdir(crashreport_uploads_dir):
40 shutil.move(crashreport_uploads_dir, crashreport_uploads_legacy_dir)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020041
42 for logfile in LogFile.objects.all():
43 migrate_logfile_instance(
44 logfile, crashreport_uploads_dir, crashreport_uploads_legacy_dir
45 )
46
47
48def migrate_logfile_instance(
49 logfile, crashreport_uploads_dir, crashreport_uploads_legacy_dir
50):
51 """Migrate a single logfile instance."""
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020052 old_logfile_relative_path = logfile.logfile.name.replace(
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020053 crashreport_uploads_dir, crashreport_uploads_legacy_dir, 1
54 )
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020055 old_logfile_absolute_path = os.path.join(
56 settings.BASE_DIR, old_logfile_relative_path
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020057 )
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020058 new_logfile_path = crashreport_file_name(
59 logfile, os.path.basename(old_logfile_relative_path)
60 )
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010061 LOGGER.info("Migrating %s", old_logfile_absolute_path)
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020062 if os.path.isfile(old_logfile_absolute_path):
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020063 update_logfile_path(logfile, new_logfile_path)
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020064 move_logfile_file(old_logfile_absolute_path, new_logfile_path)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020065 else:
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010066 LOGGER.warning("Logfile does not exist: %s", old_logfile_absolute_path)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020067
68
69def move_logfile_file(old_logfile_path, new_logfile_path):
70 """Move a logfile to a new path and delete empty directories."""
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020071 new_logfile_absolute_path = default_storage.path(new_logfile_path)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020072
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010073 LOGGER.debug("Creating directories for %s", new_logfile_absolute_path)
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020074 os.makedirs(os.path.dirname(new_logfile_absolute_path), exist_ok=True)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020075
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010076 LOGGER.debug("Moving %s to %s", old_logfile_path, new_logfile_absolute_path)
Franz-Xaver Geiger38a66bc2018-10-09 14:52:26 +020077 shutil.move(old_logfile_path, new_logfile_absolute_path)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020078
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010079 LOGGER.debug("Deleting empty directories from %s", old_logfile_path)
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020080 os.removedirs(os.path.dirname(old_logfile_path))
81
82
83def update_logfile_path(logfile, new_logfile_path):
84 """Update the path of a logfile database instance."""
Mitja Nikolaus88cc94e2018-11-23 13:47:22 +010085 LOGGER.debug(
Mitja Nikolaus6820ad02018-10-05 09:58:18 +020086 "Changing logfile path in database from %s to %s",
87 logfile.logfile,
88 new_logfile_path,
89 )
90
91 logfile.logfile = new_logfile_path
92 logfile.save()
93
94
95class Migration(migrations.Migration):
96 """Run the migration script."""
97
98 dependencies = [
99 ("crashreports", "0003_crashreport_and_heartbeat_with_radio_version")
100 ]
101
102 operations = [migrations.RunPython(migrate_logfiles)]