From 78546232d01830f41247465abaf67323cdfc9c37 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Sat, 26 Jan 2019 21:59:21 +0100
Subject: [PATCH] Fix #685: Disable makemigrations in production and misleading
 message when running migrate

---
 .../management/commands/makemigrations.py     | 22 ++++++++++++++
 .../common/management/commands/migrate.py     | 29 +++++++++++++++++++
 changes/changelog.d/685.enhancement           |  1 +
 3 files changed, 52 insertions(+)
 create mode 100644 api/funkwhale_api/common/management/commands/makemigrations.py
 create mode 100644 api/funkwhale_api/common/management/commands/migrate.py
 create mode 100644 changes/changelog.d/685.enhancement

diff --git a/api/funkwhale_api/common/management/commands/makemigrations.py b/api/funkwhale_api/common/management/commands/makemigrations.py
new file mode 100644
index 00000000..f8530f1a
--- /dev/null
+++ b/api/funkwhale_api/common/management/commands/makemigrations.py
@@ -0,0 +1,22 @@
+import os
+
+from django.core.management.base import CommandError
+from django.core.management.commands.makemigrations import Command as BaseCommand
+
+
+class Command(BaseCommand):
+    def handle(self, *apps_label, **options):
+        """
+        Running makemigrations in production can have desastrous consequences.
+
+        We ensure the command is disabled, unless a specific env var is provided.
+        """
+        force = os.environ.get("FORCE") == "1"
+        if not force:
+            raise CommandError(
+                "Running makemigrations on your Funkwhale instance can have desastrous"
+                " consequences. This command is disabled, and should only be run in "
+                "development environments."
+            )
+
+        return super().handle(*apps_label, **options)
diff --git a/api/funkwhale_api/common/management/commands/migrate.py b/api/funkwhale_api/common/management/commands/migrate.py
new file mode 100644
index 00000000..0f7b2dcd
--- /dev/null
+++ b/api/funkwhale_api/common/management/commands/migrate.py
@@ -0,0 +1,29 @@
+from django.core.management.commands.migrate import Command as BaseCommand
+
+
+def patch_write(buffer):
+    """
+    Django is trying to help us when running migrate, by checking we don't have
+    model changes not included in migrations. Unfortunately, running makemigrations
+    on production instances create unwanted migrations and corrupt the database.
+
+    So we disabled the makemigrations command, and we're patching the
+    write method to ensure misleading messages are never shown to the user,
+    because https://github.com/django/django/blob/2.1.5/django/core/management/commands/migrate.py#L186
+    does not leave an easy way to disable them.
+    """
+    unpatched = buffer.write
+
+    def p(message, *args, **kwargs):
+        if "'manage.py makemigrations'" in message or "not yet reflected" in message:
+            return
+        return unpatched(message, *args, **kwargs)
+
+    setattr(buffer, "write", p)
+
+
+class Command(BaseCommand):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        patch_write(self.stdout)
diff --git a/changes/changelog.d/685.enhancement b/changes/changelog.d/685.enhancement
new file mode 100644
index 00000000..f9cc105a
--- /dev/null
+++ b/changes/changelog.d/685.enhancement
@@ -0,0 +1 @@
+Disable makemigrations in production and misleading message when running migrate (#685)
-- 
GitLab