Repository: learningequality/kolibri
Issue: Migrations / Initialization happens without checking if another instance is running

### Observed behavior

Kolibri 0.13.0.dev runs migrations even though another instance is running, which can potentially lead to database corruption.

CC: @rtibbles 

### Expected behavior

Kolibri should immediately quit.

### User-facing consequences

Almost certainly bad.

### Errors and logs

```
➜  kolibri git:(develop) kolibri start --foreground          
WARNING:root:No C Extensions available for this platform.

INFO     Option RUN_MODE in section [Deployment] being overridden by environment variable KOLIBRI_RUN_MODE
INFO     Running Kolibri with the following settings: kolibri.deployment.default.settings.base
INFO     Version was 0.13.0.dev0+git.20190716150511, new version: 0.13.0.dev0+git.20190822215051
INFO     Running update routines for new version...
Operations to perform:
  Apply all migrations: admin, analytics, auth, content, contenttypes, device, discovery, exams, kolibriauth, lessons, logger, morango, notifications, sessions
Running migrations:
  Applying content.0019_contentnode_slideshow_options... OK
  Applying morango.0013_auto_20190627_1513... OK
Operations to perform:
  Apply all migrations: admin, analytics, auth, content, contenttypes, device, discovery, exams, kolibriauth, lessons, logger, morango, notifications, sessions
Running migrations:
  Applying content.0019_contentnode_slideshow_options... OK
  Applying morango.0013_auto_20190627_1513... OK
Installed 2 object(s) from 1 fixture(s)
INFO     Sqlite database Vacuum finished.
INFO     Running Kolibri
ERROR    Port 8080 is occupied.
Please check that you do not have other processes running on this port and try again.
```

### Steps to reproduce

Run Kolibri 0.12, so it shares directory with current `develop`. Then run `kolibri start --foreground`.

### Context

Development env. for current `develop` branch on a system with 0.12.8 installed from .deb.

### Related

The otherwise great #5494 

Changed files:
kolibri/utils/cli.py, kolibri/utils/tests/test_cli.py

diff --git a/kolibri/utils/cli.py b/kolibri/utils/cli.py
index 43743384c9..6c1a9098e2 100644
--- a/kolibri/utils/cli.py
+++ b/kolibri/utils/cli.py
@@ -334,6 +334,20 @@ def update(old_version, new_version):
 
     logger.info("Running update routines for new version...")
 
+    try:
+        # Check if there are other kolibri instances running
+        # If there are, then we need to stop users from starting kolibri again.
+        server.get_status()
+        logger.error(
+            "There is a Kolibri server running."
+            "Running updates now could cause a database error."
+            "Please use `kolibri stop` and try again."
+        )
+        sys.exit(1)
+
+    except server.NotRunning:
+        pass
+
     # Need to do this here, before we run any Django management commands that
     # import settings. Otherwise the updated configuration will not be used
     # during this runtime.
diff --git a/kolibri/utils/tests/test_cli.py b/kolibri/utils/tests/test_cli.py
index 6ef76aed0f..5296fa5f55 100755
--- a/kolibri/utils/tests/test_cli.py
+++ b/kolibri/utils/tests/test_cli.py
@@ -228,6 +228,20 @@ def test_update(update, get_version):
     update.assert_called_once()
 
 
+@pytest.mark.django_db
+@patch("kolibri.utils.cli.get_version", return_value="0.0.1")
+def test_update_exits_if_running(get_version):
+    """
+    Tests that update() function performs as expected
+    """
+    with patch("kolibri.utils.cli.server.get_status"):
+        try:
+            cli.initialize()
+            pytest.fail("Update did not exit when Kolibri was already running")
+        except SystemExit:
+            pass
+
+
 @pytest.mark.django_db
 def test_version_updated():
     """