Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

support running as a tutor plugin in production #99

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 36 additions & 18 deletions tutor-contrib-library-authoring-mfe/README.rst
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
library_authoring_mfe plugin for `Tutor <https://docs.tutor.overhang.io>`__
library_authoring_mfe plugin for `Tutor <https://docs.tutor.overhang.io>`_
===================================================================================

This plugin will setup Blockstore and the Library Authoring MFE, so you can
start using it to create v2 Libraries using Blockstore.
Installation
------------

Installation and usage
----------------------
Follow these instructions to enable this microfrontend:

**IMPORTANT**: First, you must be using `Tutor Nightly <https://docs.tutor.overhang.io/tutorials/nightly.html>`_, a
recent (July 2022 or newer) version of edx-platform (`master` branch), and the
`Tutor MFE plugin <https://github.com/overhangio/tutor-mfe/>`_.
* Install `tutor nightly <https://github.com/overhangio/tutor/tree/nightly>`_: ``pip install -e 'git+https://github.com/overhangio/tutor.git@nightly#egg=tutor'``
* Install `tutor-mfe nightly <https://github.com/overhangio/tutor-mfe/tree/nightly>`_: ``pip install -e 'git+https://github.com/overhangio/tutor-mfe.git@nightly#egg=tutor-mfe'``
* To use blockstore with `minio <https://min.io/>`_

* Install `tutor-minio <https://github.com/overhangio/tutor-minio>`_ nightly ``pip install -e 'git+https://github.com/overhangio/tutor-minio.git@nightly#egg=tutor-minio'``
* Enable minio plugin: ``tutor plugins enable minio``
* Install `tutor-contrib-blockstore-minio <https://github.com/brian-smith-tcril/tutor-contrib-blockstore-minio/>`_: ``pip install -e 'git+https://github.com/brian-smith-tcril/tutor-contrib-blockstore-minio#egg=tutor-contrib-blockstore-minio'``
* Enable the blockstore_config_minio plugin: ``tutor plugins enable blockstore_config_minio``

Then, follow these instructions to enable this microfrontend:
* To use blockstore with django :code:`FileSystemStorage`

1. Install this plugin: ``pip install -e 'git+https://github.com/openedx/frontend-app-library-authoring.git#egg=tutor-contrib-library-authoring-mfe&subdirectory=tutor-contrib-library-authoring-mfe'``
2. Enable the plugin: ``tutor plugins enable library_authoring_mfe``
3. Run ``tutor config save``.
4. Run ``tutor dev init -l library_authoring_mfe`` to set the required waffle flags in the CMS.
5. Restart your Tutor Nightly Dev environment and also start this with ``tutor dev start library-authoring``
6. Go to http://studio.local.overhang.io:8001/home/ , click "Libraries", and create a new library with
"Library Type: Complex (beta)"
* Install `tutor-contrib-blockstore-filesystem <https://github.com/brian-smith-tcril/tutor-contrib-blockstore-filesystem/>`_: ``pip install -e 'git+https://github.com/brian-smith-tcril/tutor-contrib-blockstore-filesystem#egg=tutor-contrib-blockstore-filesystem'``
* Enable the blockstore_config_filesystem plugin: ``tutor plugins enable blockstore_config_filesystem``

* Install this plugin: ``pip install -e 'git+https://github.com/brian-smith-tcril/frontend-app-library-authoring.git@tutor-prod#egg=tutor-contrib-library-authoring-mfe&subdirectory=tutor-contrib-library-authoring-mfe'``
* Enable this plugin: ``tutor plugins enable library_authoring_mfe``
* Save the tutor config: ``tutor config save``
* Build mfe image: ``tutor images build mfe`` (if you have trouble here you may need to run it with ``--no-cache``)
* Launch tutor: ``tutor local launch``

If you want to run this MFE in
`development mode <https://github.com/overhangio/tutor-mfe/#mfe-development>`
(to make changes to the code), instead of step 5 above, do this::
`development mode <https://github.com/overhangio/tutor-mfe/#mfe-development>`_
(to make changes to the code), instead of step 9 above, do this::

cd /path/to/frontend-app-library-authoring
tutor dev run --mount=. library-authoring npm install # Ensure NPM requirements are installed into your fork.
tutor dev start --mount=. library-authoring

Setup
-----
* Ensure you have created a user: https://docs.tutor.overhang.io/local.html#creating-a-new-user-with-staff-and-admin-rights
* Ensure you have created an organization: http://studio.local.overhang.io/admin/organizations/organization/
* If you're using minio

* Log in to the `minio Web UI <http://minio.local.overhang.io>`_ (`instructions to find credentials <https://github.com/overhangio/tutor-minio#web-ui>`_)
* Create a **public** bucket for blockstore (the default configuration expects the bucket to be named :code:`blockstore`)

Usage
-----
* Log in to studio: http://studio.local.overhang.io/home/
* Click on the libraries tab
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LIBRARY_AUTHORING_MICROFRONTEND_URL = "http://{{ MFE_HOST }}:{{ LIBRARY_AUTHORING_MFE_APP["port"] }}/{{ LIBRARY_AUTHORING_MFE_APP["name"] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LIBRARY_AUTHORING_MICROFRONTEND_URL = "{% if ENABLE_HTTPS %}https://{% else %}http://{% endif %}{{ MFE_HOST }}/{{ LIBRARY_AUTHORING_MFE_APP["name"] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FEATURES["ENABLE_LIBRARY_AUTHORING_MICROFRONTEND"] = True
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MFE_CONFIG_OVERRIDES.setdefault("library-authoring", {})["BLOCKSTORE_COLLECTION_UUID"] = "{{BLOCKSTORE_COLLECTION_UUID}}"
MFE_CONFIG_OVERRIDES["library-authoring"]["SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL"] = "/library-authoring/xblock-bootstrap.html"
Original file line number Diff line number Diff line change
@@ -1,52 +1,84 @@
from glob import glob
import os
import pkg_resources
import uuid

from tutor import hooks
from tutor import hooks as tutor_hooks

from .__about__ import __version__

# Enable the MFE in the CMS FEATURES configuration
hooks.Filters.ENV_PATCHES.add_item(("cms-env-features",
"ENABLE_LIBRARY_AUTHORING_MICROFRONTEND: true"
))
########################################
# CONFIGURATION
########################################

tutor_hooks.Filters.CONFIG_DEFAULTS.add_items(
[
("LIBRARY_AUTHORING_MICROFRONTEND_VERSION", __version__),
("LIBRARY_AUTHORING_MFE_APP", {
"name": "library-authoring",
"repository": "https://github.com/brian-smith-tcril/frontend-app-library-authoring",
"port": 3001,
"version": "tutor-prod", # optional
})
]
)

tutor_hooks.Filters.CONFIG_UNIQUE.add_items(
[
("BLOCKSTORE_COLLECTION_UUID", str(uuid.uuid4()))
]
)

# Set the URL of the MFE:
hooks.Filters.ENV_PATCHES.add_item(("openedx-cms-development-settings",
'LIBRARY_AUTHORING_MICROFRONTEND_URL = "http://{{ MFE_HOST }}:3001/library-authoring"'
))
# Currently Tutor does not set CMS_BASE correctly - it still defaults to 'localhost:18010' not 'localhost:8001' like we need
hooks.Filters.ENV_PATCHES.add_item(("openedx-cms-development-settings",
'CMS_BASE = "studio.local.overhang.io:8001"'
))

# Fix blockstore's file storage; by default it initializes
# BUNDLE_ASSET_STORAGE_SETTINGS using MEDIA_ROOT but before Tutor gets a chance
# to change MEDIA_ROOT so it defaults to /edx/var/edxapp/media/ which will give
# a permissions error.
hooks.Filters.ENV_PATCHES.add_item(("openedx-development-settings",
'BUNDLE_ASSET_STORAGE_SETTINGS = dict(STORAGE_CLASS="django.core.files.storage.FileSystemStorage", STORAGE_KWARGS=dict(location="/openedx/media/blockstore/", base_url="http://localhost:8000/media/blockstore/"))'
))
########################################
# INITIALIZATION TASKS
########################################

# Tell the tutor-mfe plugin about this MFE so we can build, run, and use it:
hooks.Filters.CONFIG_DEFAULTS.add_item(("LIBRARY_AUTHORING_MFE_APP", {
"name": "library-authoring",
"repository": "https://github.com/openedx/frontend-app-library-authoring",
"port": 3001,
"env": {
"development": {
# Tutor requires the name of the MFE in the URL so this file won't be found at /xblock-bootstrap.html,
# which is the default location for development.
"SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL": "/library-authoring/xblock-bootstrap.html",
"LMS_BASE_URL": "http://local.overhang.io:8000",
"STUDIO_BASE_URL": "http://studio.local.overhang.io:8001",
},
}
}))
MY_INIT_TASKS: list[tuple[str, tuple[str, ...]]] = [
("cms", ("library_authoring_mfe", "jobs", "init", "cms.sh")),
]

# Tutor overwrites webpack.dev.config.js, but this MFE depends on some code in that file to work correctly in
# development, so we have to restore it here manually.
# For each task added to MY_INIT_TASKS, we load the task template
# and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to
# run it as part of the `init` job.
for service, template_path in MY_INIT_TASKS:
full_path: str = pkg_resources.resource_filename(
"tutor_library_authoring_mfe", os.path.join("templates", *template_path)
)
with open(full_path, encoding="utf-8") as init_task_file:
init_task: str = init_task_file.read()
tutor_hooks.Filters.CLI_DO_INIT_TASKS.add_item((service, init_task))

########################################
# TEMPLATE RENDERING
########################################

tutor_hooks.Filters.ENV_TEMPLATE_ROOTS.add_items(
# Root paths for template files, relative to the project root.
[
pkg_resources.resource_filename("tutor_library_authoring_mfe", "templates"),
]
)

########################################
# PATCH LOADING
########################################

# For each file in tutor_library_authoring_mfe/patches,
# apply a patch based on the file's name and contents.
for path in glob(
os.path.join(
pkg_resources.resource_filename("tutor_library_authoring_mfe", "patches"),
"*",
)
):
with open(path, encoding="utf-8") as patch_file:
tutor_hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read()))

# Tutor overwrites webpack.dev.config.js, but this MFE depends on some code
# in that file to work correctly so we have to restore it here manually.
# https://github.com/openedx/frontend-app-library-authoring/blob/b95c198b/webpack.dev.config.js
hooks.Filters.ENV_PATCHES.add_item(("mfe-webpack-dev-config","""
tutor_hooks.Filters.ENV_PATCHES.add_item(("mfe-webpack-dev-config","""
const fs = require('fs');

// If this is the Library Authoring MFE, apply this fix:
Expand All @@ -65,14 +97,3 @@
});
}
"""))

# CMS initialization scripts to set required waffle flags:
hooks.Filters.COMMANDS_INIT.add_item((
"cms",
("library_authoring_mfe", "tasks", "cms", "init"),
))

# Configure plugin templates
hooks.Filters.ENV_TEMPLATE_ROOTS.add_item(
pkg_resources.resource_filename("tutor_library_authoring_mfe", "templates")
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Enable the waffle flag to use this MFE
(./manage.py cms waffle_flag --list | grep studio.library_authoring_mfe) || ./manage.py lms waffle_flag studio.library_authoring_mfe --create --everyone

# Make sure a Blockstore "Collection" exists to hold the library content.
# the UUID is created in CONFIG_UNIQUE in plugin.py
echo "from blockstore.apps.bundles.models import Collection; coll, _ = Collection.objects.get_or_create(title='Libraries Content Collection', uuid='{{BLOCKSTORE_COLLECTION_UUID}}')" | ./manage.py cms shell

This file was deleted.

19 changes: 19 additions & 0 deletions webpack.prod.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const path = require('path');
const { getBaseConfig } = require('@edx/frontend-build');
const { merge } = require('webpack-merge');
const CopyWebpackPlugin = require('copy-webpack-plugin');

/**
* Allow serving xblock-bootstrap.html from the MFE itself.
*/
const baseConfig = getBaseConfig('webpack-prod');
module.exports = merge(baseConfig, {
plugins: [
new CopyWebpackPlugin({
patterns: [{
context: path.resolve(__dirname, 'src/library-authoring/edit-block/LibraryBlock'),
from: 'xblock-bootstrap.html',
}],
}),
],
});