Repository: learningequality/kolibri

Issue:
create `kolibri setup` CLI command that just runs `initialize`

### Observed behavior

During setup of cloud-kolibri, @aronasorman got [this error](https://sentry.io/organizations/learningequality/issues/1071646588/?project=1378215&query=is%3Aunresolved).

It turned out that the home folder was missing, and no `kolibri_settings.json` file was available

### Expected behavior

Probably, Kolibri should exit with a helpful error message if there is no home folder or if no settings can be read.

### User-facing consequences

Unhelpful error messages in somewhat common failure scenarios

### Errors and logs

```
IndexError: list index out of range
  File "django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "django/template/response.py", line 84, in rendered_content
    content = template.render(context, self._request)
  File "django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "django/template/base.py", line 207, in render
    return self._render(context)
  File "newrelic/api/function_trace.py", line 121, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "newrelic/api/function_trace.py", line 121, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "django/template/library.py", line 203, in render
    output = self.func(*resolved_args, **resolved_kwargs)
  File "kolibri/core/templatetags/kolibri_tags.py", line 136, in kolibri_theme
    return mark_safe(template.format(theme=json.dumps(ThemeHook().theme)))
  File "kolibri/plugins/hooks.py", line 220, in inner
    return func(instance, *args, **kwargs)
  File "kolibri/core/theme_hook.py", line 135, in theme
    theme = list(self.registered_hooks)[0].theme
```

### Steps to reproduce
<!--
Precise steps that someone else can follow in order to see this behavior
-->

…

### Context
<!--
Tell us about your environment, including:
 * Kolibri version
 * Operating system
 * Browser
-->

…



Discussion:
Cloud Kolibri is in a slightly-uncommon setup where the kolibri home directory changes at least twice -- once during build time and once during runtime. In this case, we changed our kolibri home dir during runtime, but forgot to initialize it.

The normal kolibri initialization process would normally fix that, but we also run uwsgi+nginx in cloud kolibri, which makes startup faster but also doesn't run the initialization step.

So in cloud kolibri's case, it was a confluence of 2 factors:
- changing the kolibri home directory during runtime
- running uwsgi, which does not perform initialization

The solution was to run initialization in another process, then keep running health checks until the kolibri web server starts returning HTTP 200.
Our initialization is too heavily wedded to our CLI currently, so I can see unpicking this in general helping with this specific issue.
@rtibbles i was expecting a `kolibri setup` command, but didn't find it. If you can make a convenience command like that, that would be great! But otherwise, running `kolibri manage migrate `did the trick too.
Yeah - there's also the django initialization logic which only gets run when invoking from the CLI (but isn't an issue for uwsgi).

Resolving patch:
diff --git a/kolibri/utils/cli.py b/kolibri/utils/cli.py
--- a/kolibri/utils/cli.py
+++ b/kolibri/utils/cli.py
@@ -491,3 +491,11 @@ def _get_env_vars():
 @configure.command(help="List all available environment variables to configure Kolibri")
 def list_env():
     click.echo_via_pager(_get_env_vars())
+
+
+@configure.command(cls=KolibriDjangoCommand, help="Setup Kolibri")
+def setup():
+    """
+    Setup Kolibri.
+    """
+    logger.info("Kolibri has successfully been setup")


Test patch: