diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000000..606d5fa35f
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,42 @@
+# .coveragerc to control coverage.py
+[run]
+branch = True
+source =
+ ./tutor
+ ./bin
+omit =
+ */templates/*
+
+[report]
+# Regexes for lines to exclude from consideration
+exclude_lines =
+ # Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ def __repr__
+ if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.:
+
+ # Don't complain about abstract methods, they aren't run:
+ @(abc\.)?abstractmethod
+
+ignore_errors = True
+show_missing = True
+skip_empty = True
+precision = 2
+
+[html]
+skip_empty = True
+show_contexts = True
+
+[json]
+pretty_print = True
+show_contexts = True
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 69c4738060..ce5d14dfd2 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,7 +7,7 @@ assignees: ''
---
-
+
**Bug description**
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
index 74f40d0433..570e640ce6 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -4,6 +4,6 @@ about: This is not the appropriate channel
---
-Please post on our forums: https://discuss.overhang.io for questions about using `tutor`.
+Please post on our forums: https://discuss.openedx.org/tag/tutor for questions about using `tutor`.
Posts that are not a bug report or a feature/enhancement request will not be addressed on this issue tracker.
diff --git a/.github/workflows/auto-add-to-project.yml b/.github/workflows/auto-add-to-project.yml
new file mode 100644
index 0000000000..7dadeb6633
--- /dev/null
+++ b/.github/workflows/auto-add-to-project.yml
@@ -0,0 +1,17 @@
+name: Auto Add Issues to Project
+
+on:
+ issues:
+ types:
+ - opened
+
+jobs:
+ # https://github.com/actions/add-to-project
+ add-to-project:
+ name: Add issue and bugs to project
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/add-to-project@v0.5.0
+ with:
+ project-url: https://github.com/orgs/overhangio/projects/4
+ github-token: ${{ secrets.GH_PROJECT_PERSONAL_ACCESS_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..c7069dfb22
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,95 @@
+# This script can be tested locally with act:
+#
+# act --secret GITHUB_TOKEN=... --job release
+#
+# https://github.com/nektos/act/
+# To generate a token: https://github.com/settings/tokens (add r/w permissions for "Contents")
+name: Release
+
+on:
+ push:
+ tags:
+ - '*'
+ workflow_dispatch:
+
+jobs:
+ release:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ include:
+ # https://github.com/actions/runner-images#available-images
+ # It's important that we build the tutor binaries with the *oldest* possible
+ # OS releases and Python version. See these docs for more information:
+ # https://pyinstaller.org/en/stable/usage.html#making-gnu-linux-apps-forward-compatible
+ - os: ubuntu-20.04
+ locale: C.UTF-8
+ # https://endoflife.date/macos
+ - os: macos-12
+ locale: en_US.UTF-8
+ env:
+ LC_ALL: ${{ matrix.locale }}
+ LANG: ${{ matrix.locale }}
+ steps:
+ ##### Setup environment
+ # https://github.com/actions/checkout
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ # https://github.com/actions/setup-python
+ uses: actions/setup-python@v3
+ with:
+ python-version: 3.9
+ cache: 'pip'
+ cache-dependency-path: requirements/dev.txt
+ - name: Upgrade pip and setuptools
+ # https://pypi.org/project/pip/
+ # https://pypi.org/project/setuptools/
+ # https://pypi.org/project/wheel/
+ run: python -m pip install --upgrade pip setuptools==65.6.3 wheel
+ - name: Print info about the current python installation
+ run: make ci-info
+ - name: Install requirements
+ run: make bootstrap-dev-plugins
+
+ ##### Run tests, generate bundle
+ # - name: Run tests
+ # run: make test
+ - name: Create bundle
+ run: make bundle
+ # - name: Test bundle
+ # run: make ci-test-bundle
+
+ ##### Download gh utility: https://github.com/cli/cli/releases
+ # This is unnecessary on GitHub, but useful when running locally with act.
+ # WARNING: this will only work on amd64
+ - name: Check or download gh utility
+ run: |
+ if ! which gh; then
+ echo "Downloading 'gh' utility"
+ if [ "$(uname -s)" = "Linux" ]; then
+ curl -L -o gh.tar.gz https://github.com/cli/cli/releases/download/v2.28.0/gh_2.28.0_linux_amd64.tar.gz
+ tar xzf gh.tar.gz
+ mv ./gh_2.28.0_linux_amd64/bin/gh /usr/local/bin/gh
+ else
+ curl -L -o gh.zip https://github.com/cli/cli/releases/download/v2.28.0/gh_2.28.0_macOS_amd64.zip
+ unzip xzf gh.zip
+ mv ./gh_2.28.0_macOS_amd64/bin/gh /usr/local/bin/gh
+ fi
+ which gh
+ fi
+
+ ##### Create release on GitHub
+ - name: Create or update GitHub release
+ run: scriv github-release --repo=overhangio/tutor
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ # scriv command will fail when not on a tag, such as running with act or a
+ # manual trigger.
+ if: ${{ github.ref_type == 'tag' }}
+ - name: Upload release asset to GitHub
+ run: |
+ export FILENAME="tutor-$(uname -s)_$(uname -m)"
+ mv ./dist/tutor $FILENAME
+ gh release upload --clobber v$(make version) $FILENAME
+ env:
+ GH_TOKEN: ${{ github.token }}
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
new file mode 100644
index 0000000000..df0be4886e
--- /dev/null
+++ b/.github/workflows/sync.yml
@@ -0,0 +1,17 @@
+name: Sync with private repo
+
+on:
+ push:
+ branches: [ master, main, nightly ]
+
+jobs:
+ sync:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Add remote
+ run: git remote add overhangio https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@git.overhang.io/core/tutor.git
+ - name: Push
+ run: git push overhangio $GITHUB_REF
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000000..b982239229
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,40 @@
+name: Run tests
+
+on:
+ push:
+ branches: [ master, main, nightly ]
+ pull_request:
+ branches: [ master, main, nightly ]
+
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ['3.9', '3.12']
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ cache-dependency-path: requirements/dev.txt
+ - name: Upgrade pip
+ run: python -m pip install --upgrade pip setuptools
+ - name: Install dependencies
+ run: pip install -r requirements/dev.txt
+ - name: Static code analysis
+ run: make test-lint
+ - name: Python unit tests
+ run: make test-unit
+ - name: Static type checks
+ run: make test-types
+ - name: Code formatting
+ run: make test-format
+ - name: Package tests
+ run: make test-pythonpackage
+ - name: Install docs dependencies
+ run: pip install -r requirements/docs.txt
+ - name: Build docs
+ run: make docs
diff --git a/.gitignore b/.gitignore
index 4a24ea2430..d01f6874b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,7 @@ __pycache__
/build/
/dist/
-/releases/
+
+# Unit test/ coverage reports
+.coverage
+/htmlcov/
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 932deffbe4..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-language: python
-matrix:
- include:
- - os: linux
- # We need an older version of python in order to have compatibility with
- # older versions of libc
- dist: xenial
- python: 3.6
- - os: osx
- language: generic
-
-env:
- jobs:
- - PATH=/tmp/bin/:$PATH
-
-script:
- # In Mac OS python and pip binaries are v2, so we create symlinks
- - mkdir /tmp/bin && ln -s $(which python3) /tmp/bin/python && ln -s $(which pip3) /tmp/bin/pip
- - pip install --upgrade pip setuptools==44.0.0
- - make ci-info
- - make bootstrap-dev-plugins
- - make test
- - make bundle
- - make ci-test-bundle
-
-deploy:
- # Create github release and push binary to github
- - provider: script
- script: make ci-push-bundle
- skip_cleanup: true
- on:
- tags: true
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68eed7232d..4556c4f873 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,29 +1,870 @@
# Changelog
-Note: Breaking changes between versions are indicated by "π₯".
+This file includes a history of past releases. Changes that were not yet added to a release are in the [changelog.d/](./changelog.d) folder.
-## Unreleased
+
+
+
+
+
+## v18.1.4 (2024-10-24)
+
+- [Improvement] Set `EDXAPP_TEST_MONGO_HOST` env var in the openedx-dev image so that it no longer needs to be set by hand when running edx-platform unit tests (by @kdmccormick).
+
+- [Feature] Added `-c` or `--clean` option to tutor config save: For plugin developers and advanced users, this option cleans the `env/` folder before saving, ensuring a fresh environment for testing and development. (by @CodeWithEmad)
+
+- [Feature] Add a `patches show my-patch-name`. This is a convenient command for the troubleshooting of plugins. (by @regisb)
+
+- [Improvement] Fixes an issue which caused 502 errors by a premature closed connection by uwsgi, it also improves the handling of SIGTERM in docker and other uwsgi improvements (by @Ian2012).
+
+- [Improvement] Do not run useless celery workers (lms-worker, cms-worker) in development. This should save us ~700MB memory. (by @arbrandes, @regisb).
+
+- [Bugfix] Fixed an issue where the site name was not limited to 50 characters when creating a new site configuration. (by @CodeWithEmad)
+
+- [Feature] Update Open edX version to redwood.3 (by @dawoudsheraz)
+
+
+## v18.1.3 (2024-08-13)
+
+- [Feature] Update to redwood.2 tag (by @dawoudsheraz)
+
+
+## v18.1.2 (2024-07-26)
+
+- [Security] Add upstream security fix as patch in Open edX image (by @dawoudsheraz)
+
+
+## v18.1.1 (2024-07-04)
+
+- [Bugfix] Fix `mysql-native-password is not loaded` error in MySQL 8.4 when upgrading from tutor 15 or an earlier release to tutor 18 by enabling the plugin. (by @Danyal-Faheem)
+
+
+## v18.1.0 (2024-06-25)
+
+- π₯[Feature] Upgrade default charset and collation of mysql to "utf8mb4" and "utf8mb4_unicode_ci" respectively. This upgrade should be automatic for most users. However, if you are running a third-party MySQL (i.e. `RUN_MYSQL=false`), you are expected to upgrade manually. Please refer to the third-party provider's documentation for detailed upgrade instructions. Ensuring that your MySQL version is up-to-date is crucial for maintaining compatibility and security. (by @Danyal-Faheem)
+- [Bugfix] Do not fail on start when there are not persistent volume claims to apply. (by @snglth)
+- [Bugfix] Fix legacy warnings during Docker build. (by @regisb)
+
+
+## v18.0.0 (2024-06-19)
+
+- π₯[Feature] Upgrade to Redwood (by @dawoudsheraz)
+- [Bugfix] Wrap Django5 warning imports in try-except block to avoid failures in django3 that's still in use in edx-platform's master branch (by @mariajgrimaldi).
+- π₯[Feature] Pull translations via `atlas` during Docker build. This breaks the `openedx-i18n` custom locale Tutor feature in favor of [OEP-58](https://docs.openedx.org/en/latest/developers/concepts/oep58.html) in favor of . (by @omarithawi)
+- π₯[Feature] The `openedx-assets` command is replaced with `npm run` subcommands. This will slightly reduce the build time for edx-platform assets and comprehensive themes. It will also open up the door for more significant build time reductions in the future. Here is a migration guide, where each command is to be run in the `lms` or `cms` container:
+
+ **Before** | **After**
+ -----------------------------------------|-------------------------------------------------------------------------------------
+ `openedx-assets build --env=prod ARGS` | `npm run build -- ARGS`
+ `openedx-assets build --env=dev ARGS` | `npm run build-dev -- ARGS`
+ `openedx-assets common --env=prod ARGS` | `npm run compile-sass -- --skip-themes ARGS`
+ `openedx-assets common --env=dev ARGS` | `npm run compile-sass-dev -- --skip-themes ARGS`
+ `openedx-assets webpack --env=prod ARGS` | `npm run webpack -- ARGS`
+ `openedx-assets webpack --env=dev ARGS` | `npm run webpack-dev -- ARGS`
+ `openedx-assets npm` | `npm run postinstall` (`npm clean-install` runs this automatically)
+ `openedx-assets xmodule` | (no longer necessary)
+ `openedx-assets collect ARGS` | `./manage.py lms collectstatic --noinput ARGS && ./manage.py cms collectstatic ARGS`
+ `openedx-assets watch-themes ARGS` | `npm run watch-themes -- ARGS`
+
+For more details, see the [deprecation notice for paver](https://github.com/openedx/edx-platform/issues/34467)
+and the [static assets reference](https://github.com/openedx/edx-platform/tree/open-release/redwood.master/docs/references/static-assets.rst)
+in edx-platform.
+
+- π₯[Feature] Update MongoDB to v7.0.7 (by @dawoudsheraz) MongoDB is upgraded from version 4.4 to 7.0. Since there have been major releases since 4.4, the upgrade will need to go through them before running Mongo 7. MongoDB would need to follow 4.4 --> 5.0 --> 6.0 --> 7.0 upgrade path to work correctly. The container will keep on restarting with featureCompatibility error if the upgrade path is not followed. To upgrade mongo, run the following command based in the appropriate environment:
+
+ tutor upgrade --from=quince
+
+For k8s only, the above command will not perform the upgrade automatically. Instead, the command will output a series of commands that would need to be run manually to carry out the upgrade.
+
+- [Improvement] Upgrade Nodejs from 16.14.0 to 18.20.1 in edx-platform. (by @regisb)
+- [Improvement] Auto-detect bind mounts of openedx-learning for edx-platform (by @bradenmacdonald)
+- [Feature] Upgrade Open edX image to use Python 3.11 (by @dawoudsheraz)
+- [Bugfix] Remove CORS_ALLOW_HEADERS setting from the LMS/Studio config template. This setting, which holds site-agnostic application logic, is now consistently set to a reasonable value upstream by LMS and CMS config. Using the upstream values fixes a bug where course import in Studio using the new Course Authoring MFE was broken in Tutor deployments because it required additional headers to be allowed (content-range and content-disposition) (by @ormsbee)
+- [Improvement] Made Docker cache hits more frequent during the openedx image build via BuildKit's `COPY --link` feature (by @kdmccormick).
+- π₯[Improvement] Upgrade MySQL to 8.4.0. The upgrade should be automatic for most users. However, if you are running a third-party MySQL (i.e., RUN_MYSQL=false), you are expected to upgrade manually. Please refer to the third-party provider's documentation for detailed upgrade instructions. Ensuring that your MySQL version is up-to-date is crucial for maintaining compatibility and security. (by @rohansaeed)
+- π₯[Improvement] Ensure that the edx-platform repository git checkout is cached by Docker during image build. This means that the cache will automatically be cleared any time there is an upstream change. Thus, it is no longer necessary to run `tutor images build --no-cache` just to fetch the latest edx-platform changes. For this to work, any GitHub repository referenced by `EDX_PLATFORM_REPOSITORY` needs to end with ".git". Make sure that this is the case if you have modified the value of this setting in the past. (by @regisb)
+
+
+## v17.0.6 (2024-06-13)
+
+- [Feature] Introduces the IS_FILE_RENDERED Filter, which allows developers to specify files that should be copied directly without rendering. This update empowers developers to manage special file types, ensuring that they are transferred intact without undergoing template processing. (by @Abdul-Muqadim-Arbisoft)
+
+- [Improvement] Remove the obsolete `version` property from all Docker Compose files and remove the DOCKER_COMPOSE_VERSION config setting. This addresses the deprecation warning from docker-compose (version 1.27 and above) regarding `version` being obsolete. (by @jasonmokk)
+
+- [Bugfix] Fix permissions error on windows when running `tutor dev start` (by @Danyal-Faheem)
+
+
+## v17.0.5 (2024-05-22)
+
+- [Feature] Introduces the CONFIG_USER Filter. Used to declare unique key:value pairs in config.yml that will be overwritten when running tutor config save. Useful for injecting secrets from an external secrets manager into edx, or other values that may change over time that you need to programmatically fetch. (by @abonnell)
+
+- [Improvement] Add ability to patch proxy configuration for Caddy (by @ravikhetani)
+
+- [Security] Add Upstream "Privilege re-escalation in Studio after staff access removed" git security patch in Open edX Image(by @dawoudsheraz)
+
+
+## v17.0.4 (2024-04-09)
+
+- [Security] Update Redis to 7.2.4 (by @dawoudsheraz)
+
+- [Improvement] Update release to open-release/quince.3 (by @dawoudsheraz)
+
+
+## v17.0.3 (2024-03-26)
+
+- π₯[Bugfix] Prevent infinite growth of course structure cache in Redis. (by @regisb)
+ - Redis is now configured with a maximum memory size of 4GB. If this is too low for your platform, you should increase this value using the new "redis-conf" patch.
+ - Make sure that course structure cache keys have an actual timeout.
+- [Feature] Introduce the "redis-conf" patch. (by @regisb)
+- [Bugfix] Fix merge conflicts in nightly when trying to apply patches from the master branch. (by @regisb)
+- [Bugfix] Ensure mounted installable packages are installed as expected upon initialization. (by @dawoudsheraz)
+
+
+## v17.0.2 (2024-02-09)
+
+- [Feature] Several enhancements to the Demo Course (by @kdmccormick):
+ - The [Open edX Demo Course](https://github.com/openedx/openedx-demo-course) has been re-built from scratch with up-to-date instruction-focused content. Its directory structure has changed.
+ - In order to support both the old and new structures of the Demo Course's repository, the command `tutor local do importdemocourse` will now auto-determine the course root based on the location of `course.xml`. Use the `--repo-dir` argument to override this behavior.
+ - The new command `tutor local do importdemolibraries` will import any content libraries defined within the Demo Course repository. At the moment, that is just the "Respiratory System Question Bank", which is an optional but helpful extension to the new Demo Course.
+ - To try out the new Demo Course now, run: `tutor local do importdemocourse --version master`.
+ - To try out the demo Respiratory System Question Bank now, run: `tutor local do importdemolibraries --version master`.
+ - To revert back to an older Demo Course version at any point, run: `tutor local do importdemocourse --version open-release/quince.2`, replacing `quince.2` with your preferred course version.
+- [Bugfix] Remove duplicate volume declarations that cause `docker compose` v2.24.1 to fail.
+- [Bugfix] Actually update the environment on `tutor plugins enable ...`. (by @regisb)
+- [Feature] Introduce a `tutor.hooks.lru_cache` decorator that is automatically cleared whenever a plugin is loaded or unloaded. This is useful, in particular when a plugin implements a costly function that depends on tutor hooks. (by @regisb)
+- [Bugfix] Fix compatibility with Python 3.12 by replacing pkg_resources with importlib_metadata and importlib_resources. (by @Danyal-Faheem)
+- [Improvement] Upgrade base release to open-release/quince.2. (by @regisb)
+
+
+## v17.0.1 (2024-01-25)
+
+- [Bugfix] Error "'Crypto.PublicKey.RSA.RsaKey object' has no attribute 'dq'" during `tutor config save` was caused by outdated minimum version of the pycryptodome package. To resolve this issue, run `pip install --upgrade pycryptodome`. (by @regisb)
+- [Feature] add `CONFIG_INTERACTIVE` action that allows tutor plugins to interact with the configuration at the time of the interactive questionnaire that happens during tutor local launch. (by @Alec4r).
+- [Improvement] Add `.webp` and. `.otf` extensions to list of binary extensions to ignore when rendering templates.
+- [Security] Fix JWT scopes in XBlock callbacks. (by @regisb)
+
+
+## v17.0.0 (2023-12-09)
+
+- π₯[Feature] Upgrade to Quince. (by @regisb)
+- π₯[Feature] Replace "*.local.overhang.io" hostnames by "*.local.edly.io". (by @regisb)
+- π₯[Feature] Enable the Indigo theme by default, if no other theme is set. (by @regisb)
+- π₯[Deprecation] Tutor no longer supports the legacy Docker builder, which was previously available by setting `DOCKER_BUILDKIT=0` in the host environment. Going forward, Tutor will always use BuildKit (a.k.a. `docker buildx` in Docker v19-v22, or just `docker build` in Docker v23). This transition will improve build performance and should be seamless for Tutor users who are running a supported Docker version (by @kdmccormick).
+- π₯[Deprecation] The template variable `is_buildkit_enabled`, which now always returns True, is deprecated. Plugin authors should assume BuildKit is enabled and remove the variable from their templates (by @kdmccormick).
+- π₯[Deprecation] Adding Python packages to edx-platform via `private.txt` is no longer supported. Instead, users should bind-mount their requirement directories with `tutor mounts add ...`. (by @regisb)
+- [Bugfix] Updated how the Tutor setting `JWT_RSA_PRIVATE_KEY` is rendered into the LMS Django setting `JWT_AUTH['JWT_PRIVATE_SIGNING_JWK']` as required by a recent breaking upstream change. The new representation of the `JWT_PRIVATE_SIGNING_JWK` simply adds the `dq`, `dp`, and `qi` parameters. Without this fix, LMS would encounter an `InvalidKeyError` on all logins. (by @kdmccormick)
+- [Improvement] You don't have to run `tutor config save` every time you enable or disable a plugin anymore. (by @CodeWithEmad)
+
+
+## v16.1.8 (2023-12-10)
+
+- [Feature] Make it easy to work on 3rd-party edx-platform Python packages with `tutor mounts add /path/to/my/package`. (by @regisb)
+- [Improvement] When configured with `RUN_MYSQL: true`, run `mysqld` with binlog expiry set to 3 days (rather than the default of 30).
+- [Improvement] Fix `ulimits` error for elasticsearch in Docker rootless mode (by @OmarIthawi)
+- [Improvement] Do not hardcode `OPENEDX_COMMON_VERSION = master` in the nightly branch. This removes git conflicts whenever we bump the common version in the master branch. (by @regisb)
+- [Improvement] The ``iter_mounts`` template function can now take multiple image names as argument. This should concern only very advanced users. (by @regisb)
+
+
+## v16.1.7 (2023-11-17)
+
+- [Feature] Upgrade to open-release/palm.4. It is strongly recommended to upgrade to this release for as long as possible before upgrading to Quince. Otherwise, many users will be logged out after the Quince upgrade and will have to log in again -- see the Quince release notes. (by @regisb)
+- [Bugfix] Fix installation of tutor due to missing dev.txt file in Python package. (by @regisb)
+
+
+## v16.1.6 (2023-11-16)
+
+- [Feature] Upgrade to open-release/palm.4. (by @regisb)
+- [Improvement] Install tutor development tools with `pip install tutor[dev]`. (by @CodeWithEmad)
+
+
+## v16.1.5 (2023-10-30)
+
+- [Bugfix] Fix ORA2 file uploads in CMS. As the cache settings are shared between CMS and LMS, the settings are moved from `common_lms.py` to `common_all.py`. (by @FatemeKhodayari)
+
+
+## v16.1.4 (2023-10-13)
+
+- [Improvement] No more large dev images. This was fixed by adding `--no-log-init` option to useradd command and reducing space usage of `/var/log/faillog`. (by @CodeWithEmad)
+- [Improvement] Upgrade the Open edX default version to open-release/palm.3. (by @regisb)
+
+
+## v16.1.3 (2023-10-10)
+
+- [Improvement] Adds `connect=False` to the LMS and CMS' MongoDB connection to prevent `ServerSelectionError` after a cluster failover. (by @open-craft)
+- [Bugfix] Override `CMS_BASE` setting in Studio for the development environment. Without this, parts of Studio will try to use the devstack default of localhost:8010 instead. (by @ormsbee)
+- [Bugfix] Fix build error caused by py2neo package that was abruptly pulled from pypi and GitHub. (by @regisb)
+
+
+## v16.1.2 (2023-10-02)
+
+- [Bugfix] Render config settings that are inside lists. (by @regisb)
+- [Bugfix] Correctly parse strings prefixed with pound "#" key in `tutor config save --set KEY=#value` commands. (by @regisb)
+- [Feature] New action introduced: `CONFIG_LOADED`. This action is called whenever the config is loaded and makes it possible to verify the validity of configuration settings at runtime. (by @CodeWithEmad)
+- [Bugfix] Fix file upload in open response assessments. (by @regisb)
+
+
+## v16.1.1 (2023-08-29)
+
+- π₯[Bugfix] Apply "fix mysql crash after upgrade to Palm" from 16.1.0 to `tutor k8s` deployments, as well. Users previously running `tutor k8s` with `RUN_MYSQL: true`, with any version between 16.0.0 and 16.1.0 including, might have to fix their data manually. For users running `tutor local`, this change has no effect, as the underlying issue was already fixed in 16.1.0. For users running `tutor k8s` with `RUN_MYSQL: false`, this change is also a no-op. (by @fghaas)
+
+
+## v16.1.0 (2023-08-16)
+
+- [Improvement] Improve support of legacy non-BuildKit mode: (by @regisb)
+ - [Bugfix] Fix building of openedx Docker image.
+ - [Improvement] Remove `--cache-from` build option.
+ - [Improvement] Add a warning concerning the lack of support of the `--build-context` option.
+- π₯[Bugfix] Fix mysql crash after upgrade to Palm. After an upgrade to Palm, the mysql client run by Django defaults to a utf8mb4 character set and collation, but the mysql server still runs with utf8mb3. This causes broken data during migration from Olive to Palm, and more generally when data is written to the database. To resolve this issue, we explicitely set the utf8mb3 charset and collation in the client. Users who were running Palm might have to fix their data manually. In the future we will upgrade the mysql server to utf8mb4. (by @regisb)
+- [Improvement] We upgrade to MySQL 8.1.0 to avoid having to restart the server after the upgrade.
+- [Bugfix] Ask whether user wants to run locally during `tutor local launch`. (by @regisb)
+- [Bugfix] Fix a race condition that could prevent a newly provisioned Studio container from starting due to a FileExistsError when creating logs directory.
+
+
+## v16.0.5 (2023-08-09)
+
+- [Improvement] Upgrade the Open edX default version to open-release/palm.2. (by @regisb)
+
+
+## v16.0.4 (2023-08-03)
+
+- [Feature] Add support for HTTP/3, which considerably improves performance for Open edX. (by @regisb and @ghassanmas)
+- [Bugfix] Do not display discussion units when the forum is not enabled. (by @regisb)
+- [Improvement] Remove references to the wizard edition. (by @CodeWithEmad)
+
+
+## v16.0.3 (2023-07-28)
+
+- [Bugfix] Improve `tutor ... do settheme default` so that it reverts to the default theme rather than trying to switch to a nonexistent theme named "default". This will clear up some error noise from LMS/CMS logs. (by @kdmccormick)
+- [Security] Fix content libraries creation by unprivileged users in studio (see [security advisory](https://github.com/openedx/edx-platform/security/advisories/GHSA-3q74-3rfh-g37j)). (by @regisb)
+
+
+## v16.0.2 (2023-06-22)
+
+- [Bugfix] On Kubernetes, fix mysql deployment by removing the `--ignore-db-dir` option, which no longer exists on MySQL 8. (by @regisb)
+
+
+## v16.0.1 (2023-06-16)
+
+- [Bugfix] Fix loading default Kubernetes config. (by @regisb)
+
+
+## v16.0.0 (2023-06-14)
+- π₯[Feature] Upgrade to Palm. (by @regisb)
+ - [Bugfix] Rename ORA2 file upload folder from "SET-ME-PLEASE (ex. bucket-name)" to "openedxuploads". This has the effect of moving the corresponding folder from the `/data/lms/ora2` directory. MinIO users were not affected by this bug.
+ - π₯[Improvement] During registration, the honor code and terms of service links are no longer visible by default. For most platforms, these links did not work anyway.
+ - π₯[Deprecation] Halt support for Python 3.7. The binary release of Tutor is also no longer compatible with macOS 10.
+ - π₯[Deprecation] Drop support for `docker-compose`, also known as Compose V1. The `docker compose` (no hyphen) plugin must be installed.
+ - π₯[Refactor] We simplify the hooks API by getting rid of the `ContextTemplate`, `FilterTemplate` and `ActionTemplate` classes. As a consequences, the following changes occur:
+ - `APP` was previously a ContextTemplate, and is now a dictionary of contexts indexed by name. Developers who implemented this context should replace `Contexts.APP(...)` by `Contexts.app(...)`.
+ - Removed the `ENV_PATCH` filter, which was for internal use only anyway.
+ - The `PLUGIN_LOADED` ActionTemplate is now an Action which takes a single argument. (the plugin name)
+ - π₯[Refactor] We refactored the hooks API further by removing the static hook indexes and the hooks names. As a consequence, the syntactic sugar functions from the "filters" and "actions" modules were all removed: `get`, `add*`, `iterate*`, `apply*`, `do*`, etc.
+ - π₯[Deprecation] The obsolete filters `COMMANDS_PRE_INIT` and `COMMANDS_INIT` have been removed. Plugin developers should instead use `CLI_DO_INIT_TASKS` (with suitable priorities).
+ - π₯[Feature] The "openedx" Docker image is no longer built with docker-compose in development on `tutor dev start`. This used to be the case to make sure that it was always up-to-date, but it introduced a discrepancy in how images were build (`docker compose build` vs `docker build`). As a consequence:
+ - The "openedx" Docker image in development can be built with `tutor images build openedx-dev`.
+ - The `tutor dev/local start --skip-build` option is removed. It is replaced by opt-in `--build`.
+ - [Improvement] The `IMAGES_BUILD` filter now supports relative paths as strings, and not just as tuple of strings.
+ - [Improvement] Auto-complete the image names in the `images build/pull/push/printtag` commands.
+ - [Deprecation] For local installations, Docker v20.10.15 and Compose v2.0.0 are now the minimum required versions.
+ - [Bugfix] Make `tutor config printvalue ...` print actual yaml-formatted values, such as "true" and "null"
+ - π₯[Improvement] MongoDb was upgraded to 4.4.
+- π₯[Improvement] Deprecate the `RUN_LMS` and `RUN_CMS` tutor settings, which should be mostly unused. (by @regisb)
+- [Improvement] Greatly simplify ownership of bind-mounted volumes with docker-compose. Instead of running one service per application, we run just a single "permissions" service. This change should be backward-compatible. (by @regisb)
+- [Feature] Add a `config save -a/--append -A/--remove` options to conveniently append and remove values to/from list entries. (by @regisb)
+- [Improvement] Considerably accelerate building the "openedx" Docker image with `RUN --mount=type=cache`. This feature is only for Docker with BuildKit, so detection is performed at build-time. (by @regisb)
+- [Improvement] Automatically pull Docker image cache from the remote registry. Again, this will considerably improve image build-time, particularly in "cold-start" scenarios, where the images need to be built from scratch. The registry cache can be disabled with the `tutor images build --no-registry-cache` option. (by @regisb)
+- [Feature] Automatically mount host folders *at build time*. This is a really important feature, as it allows us to transparently build images using local forks of remote repositories. (by @regisb)
+- π₯[Deprecation] Remove the various `--mount` options. These options are replaced by persistent mounts, which are managed by the `tutor mounts` commands. (by @regisb)
+- [Feature] Add the `do importdemocourse --repo-dir=...` option, to import courses from subdirectories of git repositories. This allows us to import the openedx-test-course in Palm with: `tutor local do importdemocourse --repo=https://github.com/openedx/openedx-test-course --version=o
+pen-release/palm.master --repo-dir=test-course/course`. (by @regisb)
+
+
+## v15.3.7 (2023-06-13)
+
+- [Bugfix] Change `authSource` to `authsource`(LOWERCASE) in mongo db parameters. This allow to authenticate with credentials in openedx code.(by @johanv26)
+ - [Feature] Add support for loading in-cluster config when running inside a pod. In certain scenarios, Tutor may operate within a pod that has access to a cluster through role binding and a service account. In these instances, the ./kube/config file may not be present, but kubectl commands can still execute without any problems. (by @CodeWithEmad)
+- [Improvement] Bump the default MongoDB Docker image reference from version 4.2.17 to 4.2.24. (by @fghaas)
+
+
+## v15.3.6 (2023-05-22)
+
+- [Feature] Upgrade to open-release/olive.4. (by @regisb)
+
+
+## v15.3.5 (2023-04-28)
+
+- [Feature] Make it possible to import the demo course from a different git repository or version. (by @regisb)
+- [Feature] Add a convenient `do print-edx-platform-setting` command to print the value of an edx-platform setting. (by @regisb)
+- [Improvement] Improve edx-platform logging by silencing a couple deprecation warnings. (by @regisb)
+- [Feature] Add a convenient `do sqlshell` command to enter a SQL shell as root. (by @regisb)
+
+
+## v15.3.4 (2023-04-13)
+
+- [Feature] Upgrade to open-release/olive.3. (by @regisb)
+
+
+## v15.3.3 (2023-03-22)
+
+- [Improvement] Make it possible to extend or override the configuration of the uWSGI server. (by @MoisesGSalas)
+- [Improvement] Running `tutor dev launch --mount=edx-platform` now performs all necessary setup for a local edx-platform development. This includes running setup.py, installing node modules, and building assets; previously, those steps had to be run explicitly after bind-mounting a local copy of edx-platform (by @kdmccormick).
+- [Bugfix] Running jobs in development mode with `tutor dev do ...` will now correctly use the development image. Previously, it used the production image, just like `tutor local do ...`. (by @kdmccormick)
+- [Improvement] Faster build with `npm clean-install` instead of `npm install` in the openedx Docker image. This may change the version of npm packages installed next to edx-platform. (by @regisb)
+- [Feature] Introduce the `DOCKER_BUILD_COMMAND` filter which makes it possible to customize the `docker build` command. (by @regisb)
+- [Improvement] During openedx image build, copy `dockerize` utility from Docker registry for better efficiency. (by @regisb)
+- [Improvement] Better highlight enabled plugins in `tutor plugins list`. (by @regisb)
+
+- [Bugfix] Make sure that v0 plugin patches are applied in the same order as plugins are listed. (by @regisb)
+
+
+## v15.3.2 (2023-03-13)
+
+- [Bugfix] Use supported YouTube API for transcripts imports. (by @mariajgrimaldi)
+- [Feature] Add `tutor config patches list` CLI for listing available patches. (by @mafermazu)
+- [Bugfix] Add the missing `UWSGI_WORKERS` env variables to the lms and cms k8s deployments. (by @MoisesGSalas)
+
+
+## v15.3.1 (2023-02-28)
+
+- [Bugfix] `patchStrategicMerge` can now be applied to jobs. (by @keithgg)
+
+
+## v15.3.0 (2023-02-10)
+
+- [Feature] Introduce plugin indexes, described in this [Tutor enhancement proposal](https://discuss.openedx.org/t/tutor-enhancement-proposal-tep-plugin-indices/8182). This new feature introduces a lot of new ``plugins`` commands. See the docs for more information. (by @regisb)
+- [Improvement] Add the `plugins list --enabled` option. (by @regisb)
+- π₯[Improvement] Modify the output of `plugins list`. Enabled plugins are indicated as "enabled". Installed but not enabled plugins are no longer indicated as "disabled" but as "installed".
+
+- π₯[Feature] Simplify the hooks API. The modules `tutor.hooks.actions`, `tutor.hooks.filters`, and `tutor.hooks.contexts` are no longer part of the API. This change should not affect most developers, who only use the `Actions` and `Filters` classes (notice the plural) from `tutor.hooks`. (by @regisb)
+ - Instead of `tutor.hooks.actions.get("some:action")`, use `tutor.hooks.Actions.SOME_ACTION`.
+ - Instead of `tutor.hooks.filters.get("some:filter")`, use `tutor.hooks.Filters.SOME_FILTER`.
+ - Instead of `tutor.hooks.actions.add("some:action")`, use `tutor.hooks.Actions.SOME_ACTION.add()`. The same applies to the `do` method.
+ - Instead of `tutor.hooks.filters.add("some:filter")`, use `tutor.hooks.Filters.SOME_FILTER.add()`. The same applies to the `add_item`, `add_items`, `apply`, and `iterate` methods.
+ - Instead of `tutor.hooks.contexts.enter`, use `tutor.core.hooks.contexts.enter`.
+
+- [Improvement] Make it possible to override the max upload size in the LMS and the CMS. This is achieved by moving the "caddyfile-lms" and "caddyfile-cms" patches just before the `import proxy` declarations. We also wrap the `request_body` directives within `handle` statements, which means that the `max_body` sizes can be overridden for specific paths. (by @regisb)
+
+- [Security] Fix grading issue in LTI consumer XBlock. See [security advisory](https://github.com/openedx/xblock-lti-consumer/security/advisories/GHSA-7j9p-67mm-5g87). (by @regisb)
+
+- [Feature] Upgrade all Open edX services to open-release/olive.2. (by @regisb)
+
+
+## v15.2.0 (2023-01-19)
+
+- π₯[Bugfix] Fix "example.com" links in registration emails. This is a breaking change for platforms that have modified the "id" field of the LMS site object in the database. These platforms should set `SITE_ID=1` in the common settings via a plugin. (by @regisb)
+- [Bugfix] Running `tutor k8s upgrade --from=maple` won't apply and won't wait for the MySQL deployment to be ready if `RUN_MYSQL: false` (When you host your MySQL somewhere else like RDS) (by @CodeWithEmad)
+- [Bugfix] Fix HTML component editing in studio by cherry-picking [upstream fix](https://github.com/openedx/edx-platform/pull/31500). (by @regisb)
+- [Improvement] Changes annotations from `typing` to use built-in generic types from `__future__.annotations` (by @Carlos-Muniz)
+- [Improvement] Resolve `CORS_ORIGIN_WHITELIST` warnings that pollute the LMS and CMS logs. As far as we know they were not causing any issue, apart from being a nuisance. (by @regisb)
+
+
+## v15.1.0 (2022-12-13)
+
+- [Improvement] Upgrade ipdb and ipython packages in the openedx development image. (by @regisb)
+- [Improvement] Skip unnecessary image building in development. This should make `tutor dev launch` slightly faster. (by @regisb)
+- [Bugfix] Fix Authn MFE login in development by disabling enterprise integration. (by @regisb)
+- [Bugfix] Fix "Invalid value for β--fromβ" when running `tutor local upgrade --from=nutmeg`. If you are facing this error, just run `tutor local launch` and your platform should be automatically upgraded.
+- [Bugfix] Fix "TypeError: Parameters to Generic[...] must all be type variables" error. This error may occur when upgrading from a very old installation of Tutor. It is due to an old version of the typing-extensions package.
+- π₯[Deprecation] Get rid of the `quickstart` command. v15.0.0 introduced a deprecation warning, but we actually want users to stop using this command. Instead, use `launch` (by @regisb).
+- [Improvement] Backfill persistent grades during upgrade from Nutmeg. If you observe missing grades after the upgrade from Nutmeg, run `tutor local upgrade --from=nutmeg`. (by @regisb)
+
+
+## v15.0.0 (2022-12-06)
+
+- π₯[Feature] Upgrade to Olive (by @regisb):
+ - Mypy type checking options were modified: developers are encouraged to add the `--implicit-reexport` option to their IDE.
+- [Bugfix] Update problem templates according newer python versions. (by @mariajgrimaldi)
+- [Improvement] Add the `-h` help option to all commands and subcommands. Previously, we could only use `--help`, which is quite long for lazy fingers. (by @regisb)
+- π₯[Feature] Add an extensible `local/dev/k8s do ...` command to trigger custom job commands. These commands are used to run a series of bash scripts in designated containers. Any plugin can add custom jobs thanks to the `CLI_DO_COMMANDS` filter. This causes the following breaking changes:
+ - The "init", "createuser", "settheme", "importdemocourse" commands were all migrated to this new interface. For instance, `tutor local init` was replaced by `tutor local do init`.
+ - Plugin developers are encouraged to replace calls to the `COMMANDS_INIT` and `COMMANDS_PRE_INIT` filters by `CLI_DO_INIT_TASKS`.
+- [Feature] Implement hook filter priorities, which work like action priorities. (by @regisb)
+- π₯[Improvement] Remove the `local/dev bindmount` commands, which have been marked as deprecated for some time. The `--mount` option should be used instead.
+- π₯[Bugfix] Fix local installation requirements. Plugins that implemented the "openedx-dockerfile-post-python-requirements" patch and that needed access to the edx-platform repo will no longer work. Instead, these plugins should implement the "openedx-dockerfile-pre-assets" patch. This scenario should be very rare, though. (by @regisb)
+- π₯[Improvement] Rename the implementation of tutor quickstart to tutor launch. (by @Carlos-Muniz)
+- π₯[Improvement] Remove the implementation of tutor dev runserver. (by @Carlos-Muniz)
+- [Bugfix] Fix MongoDB replica set connection error resulting from edx-platform's pymongo (3.10.1 -> 3.12.3) upgrade ([edx-platform#30569](https://github.com/openedx/edx-platform/pull/30569)). (by @ormsbee)
+- [Bugfix] Update ``celery`` invocations for lms-worker and cms-worker to be compatible with Celery 5 CLI.
+- [Improvement] Point CMS at its config file using ``CMS_CFG`` environment variable instead of deprecated ``STUDIO_CFG``.
+
+
+## v14.2.3 (2022-12-06)
+
+- [Security] Fix rotation of JWT tokens for disabled users. (by @regisb)
+
+
+## v14.2.2 (2022-11-29)
+
+- [Bugfix] Fix `jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got '|'` error by bumping the minimum required version of the Jinja2 package.
+
+- [Feature] Add support for MongoDB SSL, authentication source, mechanism and replica set via the `MONGODB_USE_SSL`, `MONGODB_AUTH_MECHANISM`, `MONGODB_AUTH_SOURCE`, `MONGODB_REPLICA_SET` settings. (by @zakum1 and @regisb)
+
+- [Bugfix] Fix tag of "openedx" development Docker image. Previously, this Docker tag did not include the Tutor version. As a consequence, a different cached image could be used in some cases. For instance: when running `tutor dev run` commands. Now, the image tag is "openedx-dev:TUTOR_VERSION".
+
+- [Bugfix] Fix name of Swahili locale: it is "sw-ke" and not "sw" (by @regisb).
+
+- [Security] Apply drag-n-drop v2 xblock [security patch](https://discuss.openedx.org/t/upcoming-security-release-xblock-drag-and-drop-v2/8768/7). (by @regisb)
+
+
+## v14.2.1 (2022-11-24)
+
+- [Improvement] Auto-completion of `plugins` and `config` arguments: `plugins enable/disable NAME`, `plugins install PATH`, `config save --set KEY=VAL`, `config save --unset KEY`, `config printvalue KEY`. (by @regisb)
+- [Bugfix] Fix minimum click version (>= 8.0.0) when installing tutor from pip.
+- [Improvement] Enable CORS by default for both LMS and CMS by moving those settings to the `common_all` partial. (by @arbrandes)
+
+## v14.2.0 (2022-11-21)
+
+- [Improvement] Auto-complete implicit `local/dev --mount /path/to/...` options. (by @regisb)
+- π₯[Feature] Strong typing of action and filter hooks: this allows us to detect incorrect calls to `actions.add` or `filters.add` early. Strong typing forces us to break the `do` and `apply` API by removing the `context` named argument. Developers should replace `do(context=...)` by `do_from_context(..., )` (and similar for `apply`).
+
+## v14.1.2 (2022-11-02)
+
+- [Security] Fix edx-platform XSS vulnerability on "next" parameter. (by @regisb)
+
+## v14.1.1 (2022-10-25)
+
+- [Deprecation] Tutor is no longer compatible with Python 3.6. (by @regisb)
+- [Security] Fix xblock ajax handler vulnerability. (by @regisb)
+- [Improvement] Use web proxy gzip encoding to improve bandwidth. We observe a 75% size reduction on the LMS dashboard. (by @ghassanmas)
+
+## v14.1.0 (2022-10-10)
+
+- [Improvement] Upgrade Scorm XBlock to v14.0.0. (by @regisb)
+- π₯[Improvement] The Richie plugin was transferred to the Openfun organization; thus, it is no longer officially supported and it is removed from the default set of plugins that ships with `pip install tutor[full]` or the Tutor pre-compiled binary. Users are encouraged to uninstall the `tutor-richie` Python package and install the `tutor-contrib-richie` package instead.
+- [Feature] Upgrade edx-platform i18n strings to nutmeg.2. (by @regisb)
+
+## v14.0.5 (2022-08-29)
+
+- [Bugfix] Fix MongoDB replica set connection error resulting from edx-platform's pymongo (3.10.1 -> 3.12.3) upgrade ([edx-platform#30569](https://github.com/openedx/edx-platform/pull/30569)). (by @ormsbee)
+- [Feature] Upgrade all applications to open-release/nutmeg.2. (by @BbrSofiane)
+
+## v14.0.4 (2022-07-29)
+
+- [Feature] Add the `-m/--mount` option to `tutor dev quickstart`. (by @regisb)
+- [Bugfix] Fix `tutor dev start -m /path/to/frontend-app-learning` by introducing dev-specific `COMPOSE_DEV_TMP` and `COMPOSE_DEV_JOBS_TMP` filters (by @regisb).
+- [Bugfix] Log the shell commands that Tutor executes more accurately. (by @kdmccormick)
+- [Bugfix] `tutor dev quickstart` would fail under certain versions of docker-compose due to a bug in the logic that handled volume mounting. (by @kdmccormick)
+- [Bugfix] The `tutor k8s start` command will succeed even when `k8s-override` and `kustomization-patches-strategic-merge` are not specified. (by @edazzocaisser)
+- [BugFix] `kubectl wait` checks deployments instead of pods as it could hang indefinitely if there are extra pods in a broken state. (by @keithgg)
+
+## v14.0.3 (2022-07-09)
+
+- [Bugfix] Build openedx-dev Docker image even when the host user is root, for instance on Windows. (by @regisb)
+- [Bugfix] Patch nutmeg.1 release with [LTI 1.3 fix](https://github.com/openedx/edx-platform/pull/30716). (by @ormsbee)
+- [Improvement] Make it possible to override k8s resources in plugins using `k8s-override` patch. (by @foadlind)
+
+## v14.0.2 (2022-06-27)
+
+- [Bugfix] Update problem with hint template so it works with newer python versions. (by @mariajgrimaldi)
+- [Feature] Add default PYTHONBREAKPOINT to openedx/Dockerfile (by @Carlos-Muniz)
+- [Bugfix] Fix smtp server port in `cms.yml` which was causing email sending failures in the Studio. (by @regisb)
+- [Bugfix] Skip waiting for MongoDB if it is served using SRV records. (by @gabor-boros)
+- [Improvement] Use `git am` instead of `cherry-pick` to simplify patching process.
+- [Improvement] Tutor is now compatible with Docker Compose subcommand.
+
+## v14.0.1 (2022-06-13)
+
+- [Bugfix] Fix missing tables on migration from maple ([#689](https://github.com/overhangio/tutor/issues/689)). (by @ibrmora)
+- [Bugfix] Fix plugin patches in cms.env.yml template.
+
+## v14.0.0 (2022-06-09)
+
+- π₯[Feature] Upgrade to Nutmeg: (by @regisb)
+ - π₯[Feature] Hide a course from the `/course` search page in the LMS when the course visibility is set to "none" in the Studio. (thanks @ghassanmas!)
+ - π₯[Improvement] The `lms.env.json` and `cms.env.json` files are moved to `lms.env.yml` and `cms.env.yml`. As a consequence, plugin developers must reformat the following patches to use YAML format, and not JSON: "common-env-features", "lms-env-features", "cms-env-features", "lms-env", "cms-env", "openedx-auth".
+ - π₯[Feature] Persistent grades are now enabled by default.
+ - [Bugfix] Remove edX references from bulk emails ([issue](https://github.com/openedx/build-test-release-wg/issues/100)).
+ - [Improvement] For Tutor Nightly (and only Nightly), official plugins are now installed from their nightly branches on GitHub instead of a version range on PyPI. This will allow Nightly users to install all official plugins by running ``pip install -e ".[full]"``.
+ - [Bugfix] Start MongoDB when running migrations, because a new data migration fails if MongoDB is not running
+
+## v13.3.1 (2022-06-06)
+
+- [Bugfix] Crashing celery workers in development (#681). (by @regisb)
+- [Bugfix] Fix studio logout issue. (by @Alec4r)
+
+## v13.3.0 (2022-06-03)
+
+- [Security] Apply logout redirect url security fix. (by @regisb)
+- [Feature] Make it possible to force the rendering of a given template, even when the template path matches an ignore pattern. (by @regisb)
+- π₯[Bugfix] Get rid of the `tutor config render` command, which is useless now that themes can be implemented as plugins. (by @regisb)
+
+## v13.2.3 (2022-05-30)
+
+- [Bugfix] Truncate site display name to 50 characters with a warning, fixing data too long error for long site names. (by @navinkarkera)
+- [Feature] Add patch to allow overriding final openedx docker image CMD.
+- [Bugfix] Ignore Python plugins that cannot be loaded. (by @regisb)
+- [Improvement] Faster and more reliable builds with `npm clean-install` instead of `npm install`. (by @regisb. Thanks @ghassanmas!)
+- [Bugfix] Fix 500 error during studio login. (by @regisb)
+- [Bugfix] Fix updates for the Caddy deployment in multi-node Kubernetes clusters (#660). Previously, Caddy configuration updates might fail if the Kubernetes cluster had more than one worker node. (by @fghaas)
+
+## v13.2.2 (2022-05-06)
+
+- [Bugfix] Mounts were broken in dev mode. (by @kdmccormick)
+
+## v13.2.1 (2022-05-06)
+
+- [Bugfix] Fix broken file upload in studio because of unpinned studio-frontend requirement (see [discussion](https://discuss.overhang.io/t/missing-js-css-files-missing-from-openedx-docker-image-in-studio/2629) and [pull request](https://github.com/openedx/edx-platform/pull/30309)) (by @regisb. Thanks @uetuluk!).
+- [Bugfix] "The Compose file is invalid" error on mounting dev-only folders. (by @regisb)
+- [Bugfix] CMS settings in development. (by @regisb)
+
+## v13.2.0 (2022-04-24)
+
+- [Improvement] Add the `COMPOSE_PROJECT_STARTED` action and run `dev stop` on `local start` (and vice versa). (by @regisb)
+- [Feature] Introduce `local/dev copyfrom` command to copy contents from a container. (by @regisb)
+- [Bugfix] Fix a race condition that could prevent a newly provisioned LMS container from starting due to a `FileExistsError` when creating data folders.
+- [Deprecation] Mark `tutor dev runserver` as deprecated in favor of `tutor dev start`. Since `start` now supports bind-mounting and breakpoint debugging, `runserver` is redundant and will be removed in a future release. (by @kdmccormick)
+- [Improvement] Allow breakpoint debugging when attached to a service via `tutor dev start SERVICE`. (by @kdmccormick)
+- [Security] Apply rate limiting security fix (see [commit](https://github.com/overhangio/edx-platform/commit/b5723e416e628cac4fa84392ca13e1b72817674f)). (by @regisb)
+- [Feature] Introduce the ``-m/--mount`` option in ``local`` and ``dev`` commands to auto-magically bind-mount folders from the host. (by @regisb)
+- [Feature] Add `tutor dev quickstart` command, which is similar to `tutor local quickstart`, except that it uses dev containers instead of local production ones and includes some other small differences for the convience of Open edX developers. This should remove some friction from the Open edX development setup process, which previously required that users provision using local producation containers (`tutor local quickstart`) but then stop them and switch to dev containers (`tutor local stop && tutor dev start -d`). (by @kdmccormick)
+- π₯[Improvement] Make it possible to run `tutor k8s exec ` (#636). As a consequence, it is no longer possible to run quoted commands: `tutor k8s exec ""`. Instead, you should remove the quotes: `tutor k8s exec `. (by @regisb)
+- π₯[Deprecation] Drop support for the `TUTOR_EDX_PLATFORM_SETTINGS` environment variable. It is now recommended to create a plugin instead. (by @regisb)
+- π₯[Improvement] Complete overhaul of the plugin extension mechanism. Tutor now has a hook-based Python API: actions can be triggered at different points of the application life cycle and data can be modified thanks to custom filters. The v0 plugin API is still supported, for backward compatibility, but plugin developers are encouraged to migrate their plugins to the new API. See the new plugin tutorial for more information. (by @regisb)
+- [Improvement] Improved the output of `tutor plugins list`. (by @regisb)
+- [Feature] Add `tutor [dev|local|k8s] status` command, which provides basic information about the platform's status. (by @kdmccormick)
+
+## v13.1.11 (2022-04-12)
+
+- [Security] Apply SAML security fix.
+- [Improvement] In addition to the Docker build arguments `EDX_PLATFORM_REPOSITORY` and `NPM_REGISTRY`, also support two corresponding and identically-named `config.yml` values serving the same purpose.
+
+## v13.1.10 (2022-04-11)
+
+- [Feature] Upgrade all applications to open-release/maple.3.
+
+## v13.1.9 (2022-04-06)
+
+- [Security] Fix open redirect vulnerability in inactive user flow (see [commit](https://github.com/rgraber/edx-platform/commit/fbbcfe71832e700f16aad3636b0ccb35585d1c95))
+
+## v13.1.8 (2022-03-18)
+
+- [Bugfix] Fix "evalsymlink failure" during `k8s quickstart` (#611).
+- [Bugfix] Fix "TypeError: upgrade() got an unexpected keyword argument 'non_interactive'" during `local upgrade`.
+
+## v13.1.7 (2022-03-17)
+
+- [Bugfix] Fix dockerize on arm64 by switching to the [powerman/dockerize](https://github.com/powerman/dockerize) fork (#591).
+- [Bugfix] Fix "Unexpected args" error during service initialisation on Kubernetes (#611).
+
+## v13.1.6 (2022-03-15)
+
+- [Bugfix] Fix `local/k8s quickstart` commands when upgrading from an older release (#595).
+- [Bugfix] Fix running the default exim-relay SMTP server on arm64 (#600).
+- [Feature] Add `tutor k8s apply` command, which is a direct interface with `kubectl apply`.
+- [Feature] Add `openedx-dockerfile-minimal` patch, which you can use to install custom packages and run commands as root in the Docker image.
+
+## v13.1.5 (2022-02-14)
+
+- [Improvement] Upgrade all services to open-release/maple.2.
+
+## v13.1.4 (2022-02-08)
+
+- [Security] Fix vulnerability in redirect URL during authentication (see [commit](https://github.com/overhangio/edx-platform/commit/06550411e34c04376fa3d757e1f068f464f816e6)).
+
+## v13.1.3 (2022-02-01)
+
+- [Security] Fix vulnerability in call to invalid enrollment API (see [commit](https://github.com/openedx/edx-platform/commit/a140c674799c527e961e37c5e46cb7dc1ffef5ac)).
+- [Bugfix] Fix "Internal Server Error / AttributeError / object has no attribute 'get_metadata'" in learning MFE.
+- [Improvement] Replace all links to github.com/edx by github.com/openedx, following the migration of all repositories.
+- [Bugfix] Fix `k8s start caddy` command.
+
+## v13.1.2 (2022-01-30)
+
+- [Bugfix] Fix auto-renewal of certificates revoked by Let's Encrypt (see [discussion](https://community.letsencrypt.org/t/questions-about-renewing-before-tls-alpn-01-revocations/170449/21)).
+
+## v13.1.1 (2022-01-25)
+
+- [Bugfix] Fix authentication in development due to missing SameSite policy on session ID cookie.
+- [Bugfix] Display properly themed favicon.ico image in LMS, Studio, and microfrontends.
+- [Bugfix] Fix "LazyStaticAbsoluteUrl is not JSON serializable" error when sending bulk emails.
+- [Bugfix] Fix `tutor local importdemocourse` fails when the platform is not up.
+
+## v13.1.0 (2022-01-08)
+
+- [Improvement] Provide much more comprehensive instructions when upgrading.
+- [Bugfix] During the upgrade, make sure that the environment is up-to-date before prompting to rebuild the custom images.
+- [Bugfix] Fix ownership of MySQL data, in particular when upgrading a Kubernetes cluster to Maple.
+- [Bugfix] Ensure that ``tutor k8s upgrade`` is run during ``tutor k8s quickstart``, when necessary.
+- π₯[Bugfix] By default, detect the current version during ``tutor k8s/local upgrade``.
+- [Bugfix] Fix upgrading from Lilac to Maple on Kubernetes by deleting deployments and services.
+
+## v13.0.3 (2022-01-04)
+
+- [Security] Upgrade Django to 3.2.11 in edx-platform.
+- [Security] Prevent non-staff users from searching usernames by email by abusing the logout URL.
+
+## v13.0.2 (2021-12-22)
+
+- [Security] Prevent non-staff users from searching usernames by email.
+
+## v13.0.1 (2021-12-20)
+
+- [Bugfix] Missing requirements file in `pip install tutor[full]`.
+
+## v13.0.0 (2021-12-20)
+
+- π₯[Improvement] Upgrade to Maple
+ - Install all official plugins as part of the `tutor[full]` package.
+ - Don't print error messages about loading plugins during autocompletion.
+ - Prompt for image building when upgrading from one release to the next.
+ - π₯ Allow concurrent logins to the LMS and the CMS.
+ - Add `tutor local start --skip-build` option to skip building Docker images.
+- [Feature] Better support of Caddy as a load balancer in Kubernetes:
+ - Make it possible to start/stop a selection of resources with ``tutor k8s start/stop [names...]``.
+ - Make it easy to deploy an independent LoadBalancer by converting the caddy service to a ClusterIP when ``ENABLE_WEB_PROXY=false``.
+ - Add a ``app.kubernetes.io/component: loadbalancer`` label to the LoadBalancer service.
+ - Add ``app.kubernetes.io/name`` labels to all services.
+ - Preserve the LoadBalancer service in ``tutor k8s stop`` commands.
+ - Wait for the caddy deployment to be ready before running initialisation jobs.
+ - Fix running Caddy container in k8s, which should always be the case even if `ENABLE_WEB_PROXY` is false.
+- [Security] On Kubernetes, convert all NodePort services to ClusterIP to guarantee network isolation from outside the cluster.
+- π₯[Improvement] Move the Open edX forum to a [dedicated plugin](https://github.com/overhangio/tutor-forum/) (#450).
+- π₯[Improvement] Drop Python 3.5 compatibility.
+- π₯[Bugfix] No longer track the Tutor version number in resource labels (and label selectors, which breaks the update of Deployment resources), but instead do so in resource annotations.
+- π₯[Improvement] Get rid of the "tutor-openedx" package, which is no longer supported.
+- π₯[Improvement] Run all services as unprivileged containers, for better security. This has multiple consequences:
+ - The "openedx-dev" image is now built with `tutor dev dc build lms`.
+ - The "smtp" service now runs the "devture/exim-relay" Docker image, which is unprivileged. Also, the default SMTP port is now 8025.
+- π₯[Feature] Get rid of the Nginx container and service, which is now replaced by Caddy. this has the following consequences:
+ - Patches "nginx-cms", "nginx-lms", "nginx-extra", "local-docker-compose-nginx-aliases" are replaced by "caddyfile-cms", "caddyfile-lms", "caddyfile", " local-docker-compose-caddy-aliases".
+ - Patches "k8s-deployments-nginx-volume-mounts", "k8s-deployments-nginx-volumes" were obsolete and are removed.
+ - The `NGINX_HTTP_PORT` setting is renamed to `CADDY_HTTP_PORT`.
+- [Bugfix] Fix building of the `openedx` image on ARM64 due to missing `libgeos-dev`
+
+## v12.2.0 (2021-12-08)
+
+- [Bugfix] Fix incorrect "from" address in course bulk emails (see [pull request](https://github.com/openedx/edx-platform/pull/29001)).
+- π₯[Improvement] Fail on incorrect image name argument in `images build/pull/push/printtag` commands.
+- [Bugfix] Remove trailing slashes in docker-compose files for [compatibility with docker-compose v2 in WSL](https://github.com/docker/compose/issues/8558).
+- [Improvement] `settheme` now works with the preview domain.
+- [Feature] Allow specifying extra pip packages through config.yml.
+
+## v12.1.7 (2021-11-18)
+
+- [Security] Timed exam security fix [29347](https://github.com/openedx/edx-platform/pull/29347).
+- [Feature] Add [tutor-richie](https://github.com/overhangio/tutor-richie) to the plugins that are bundled with the tutor binary.
+- [Improvement] Make `tutor plugins list` print plugins sorted by name.
+- [Improvement] Ignore Python plugins that cannot be loaded.
+- [Bugfix] When configured with `RUN_FORUM: false`, omit forum-related [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/) from the manifests that `tutor k8s` generates. (#525)
+
+## v12.1.6 (2021-11-02)
+
+- [Improvement] Upgrade all services to open-release/lilac.3.
+- [Feature] Make it possible to override job configuration in development: if they exist, `dev/docker-compose.jobs.yml` and `dev/docker-compose.jobs.override.yml` will be loaded when running jobs.
+- [Improvement] Faster `tutor local start` by building only necessary images.
+
+## v12.1.5 (2021-10-25)
+
+- π₯[Improvement] Change the `settheme` command such that, by default, a custom theme is assigned to the LMS and the CMS, both in production and development mode.
+- [Bugfix] Change the `local quickstart` command to check for adequate Docker memory allocation on macOS (#463)
+
+## v12.1.4 (2021-10-11)
+
+- [Feature] Add configuration setting `PREVIEW_LMS_BASE` for custom preview domain.
+- [Improvement] Enable milestones application flag `MILESTONES_APP` and prerequisite courses feature flags `ENABLE_PREREQUISITE_COURSES` by default.
+
+## v12.1.3 (2021-09-28)
+
+- [Bugfix] Fix 500 error during user registration.
+- [Bugfix] Fix Mongodb compatibility version upgrade when upgrading from Koa to Lilac.
+- [Feature] Ability to pass [docker build options](https://docs.docker.com/engine/reference/commandline/build/#options) via ``--docker-arg`` option in ``tutor images build`` command.
+
+## v12.1.2 (2021-09-18)
+
+- [Bugfix] Fix (again) forum starting issue: "NoMethodError: undefined method 'encode' for nil:NilClass".
+
+## v12.1.1 (2021-09-17)
+
+- [Bugfix] Fix forum starting issue: "NoMethodError: undefined method 'encode' for nil:NilClass".
+
+## v12.1.0 (2021-09-17)
+
+- [Improvement] Make it easier to run edx-platform unit tests.
+- [Bugfix] Fix segmentation fault during `tutor config save` on Mac OS M1 (#473). Thanks @ghassanmas!
+- [Bugfix] Fix a bug that prevented connecting to external MongoDB instances.
+- [Improvement] Make sure that the logo included in email notifications (including discussion responses) is the same as the site logo.
+- [Bugfix] Install IPython directly from PyPI instead of installing it from source (the reason it was installed from source is no longer relevant). The effect of this shall speed up the process of building the openedx-dev Docker image.
+- [Feature] Add "openedx-dockerfile-post-git-checkout" patch.
+- [Improvement] In the "openedx" Docker images, convert git patches to cherry-picks for a cleaner source tree.
+- π₯[Feature] Make it possible to override local job configuration. This deprecates the older model for running jobs which dates back from a long time ago.
+
+## v12.0.4 (2021-08-12)
+
+- [Security] Apply security patch [28442](https://github.com/openedx/edx-platform/pull/28442).
+
+## v12.0.3 (2021-08-10)
+
+- [Improvement] Upgrade all services to open-release/lilac.2.
+- [Bugfix] Fix "`sh` is not a recognized command" in some plugins, including minio.
+- [Improvement] Set the default contact mailing email address
+- [Bugfix] Fix minio initialisation in Kubernetes.
+
+## v12.0.2 (2021-07-06)
+
+- [Bugfix] Fix "Invalid command argument" during upgrade from Koa to Lilac.
+- [Bugfix] Fix MySQL initialisation in docker-compose==2.0.0beta4.
+- [Improvement] Tutor is now published on PyPI as "tutor".
+
+## v12.0.1 (2021-06-22)
+
+- [Bugfix] Fix double pulling MongoDB image when upgrading from Koa to Lilac.
+- [Improvement] Better logging during `plugins disable`.
+- [Bugfix] Fix "upstream sent too big header" error during login of existing users after a Koa to Lilac upgrade.
+- [Feature] Added the ability to skip `config.yml` file modification while running `tutor config save` command with `-e` or `--env-only` flag.
+- [Feature] Add new config value `FORUM_MONGODB_DATABASE` to set the forum database name.
+
+## v12.0.0 (2021-06-09)
+
+- π₯[Improvement] Upgrade all services to open-release/lilac.master.
+- π₯[Feature] Migrate Android app building and the WebUI frontend away from core Tutor and to dedicated plugins (see [TEP](https://discuss.overhang.io/c/community/tep/9)). The `DOCKER_IMAGE_ANDROID` setting is thus renamed to `ANDROID_DOCKER_IMAGE`.
+- [Feature] Run `docker-compose build` as part of `tutor local start`.
+
+## v11.3.1 (2021-06-08)
+
+- [Improvement] Avoid permission issues in Kubernetes/Openshift for users who do not have the rights to edit their namespace.
+- [Improvement] Better Kubernetes object creation.
+
+## v11.3.0 (2021-06-06)
+
+- π₯[Security] Disable python-evaluated input by default as we don't run codejail.
+- [Bugfix] Fix missing discussion notifications.
+- [Improvement] Better error logging when loading a plugin from an incompatible version.
+
+## v11.2.11 (2021-05-18)
+
+- [Feature] Add Redis database configuration for both cache and celery.
+
+## v11.2.10 (2021-05-17)
+
+- [Security] Apply Django security patches by upgrading from 2.2.20 to 2.2.23.
+- [Bugfix] Fix video unit completion (see [pull request](https://github.com/openedx/edx-platform/pull/27230)).
+
+## v11.2.9 (2021-05-12)
+
+- [Bugfix] Fix crashing installation because of a major release of all Pallets projects.
+- [Bugfix] Fix crash in `local quickstart -p` command.
+- [Bugfix] Fix 502 error on request to lms with header larger than the maximum uwsgi buffer size.
+
+## v11.2.8 (2021-04-27)
+
+- [Bugfix] Fix parsing of YAML-formatted values in ``config save --set KEY=VALUE`` commands, in use for instance with Ecommerce.
+
+## v11.2.7 (2021-04-23)
+
+- [Security] Apply security patch [27394](https://github.com/openedx/edx-platform/pull/27394).
+- [Feature] Add patches to extend python requirements installation process in openedx and openedx-dev Dockerfiles.
+- [Improvement] Apply edx-platform patches during Docker image build using tutor patch 'openedx-dockerfile-git-patches-default'.
+
+## v11.2.6 (2021-04-09)
+
+- [Improvement] Upgrade all services to open-release/koa.3.
+- [Feature] Make it possible to build the openedx Docker image with a custom openedx-i18n version with the ``--build-arg OPENEDX_I18N_VERSION=custom`` command line argument.
+
+## v11.2.5 (2021-03-30)
+
+- [Bugfix] Fix edge case where `PLUGINS` entry is null in config.yml.
+- [Bugfix] Fix missing py2neo dependency in `images build openedx` (#411).
+
+## v11.2.4 (2021-03-17)
+
+- [Bugfix] Fix "Invalid Request" error during SAML authentication (thanks @Ant1x!).
+- [Feature] Add `make pull-base-images` command to update base images.
+- [Improvement] Annotate types all over the Tutor code base.
+- [Bugfix] Fix parsing of YAML CLI arguments that include equal "=" signs.
+- [Bugfix] Fix minor edge case in `long_to_base64` utility function.
+- [Improvement] Add openedx patches to add settings during the build process.
+
+## v11.2.3 (2021-02-20)
+
+- [Bugfix] Make LMS celery workers actually process LMS tasks and not CMS tasks.
+
+## v11.2.2 (2021-02-17)
+
+- [Security] Apply security patch [26592](https://github.com/openedx/edx-platform/pull/26592).
+
+## v11.2.1 (2021-02-16)
+
+- [Bugfix] Actually persist Redis data.
+
+## v11.2.0 (2021-02-10)
+
+- [Bugfix] Upgrade all services to open-release/koa.2.
+
+## v11.1.5 (2021-02-09)
+
+- [Security] Apply security patch [26432](https://github.com/openedx/edx-platform/pull/26432).
+- [Bugfix] Print warnings to stderr.
+
+## v11.1.4 (2021-02-04)
+
+- [Security] Apply security patch [26358](https://github.com/openedx/edx-platform/pull/26358).
+
+## v11.1.3 (2021-01-31)
+
+- [Security] Apply security patch [26253](https://github.com/openedx/edx-platform/pull/26253).
+
+## v11.1.2 (2021-01-29)
+
+- [Bugfix] Fix django setting value and static asset loading in openedx-dev image.
+
+## v11.1.1 (2021-01-20)
+
+- [Feature] Add a `tutor images build --target=...` argument for [multi-stage Docker builds](https://docs.docker.com/develop/develop-images/multistage-build/).
+- [Feature] Create a test version of the openedx-dev Docker image for running edx-platform unit tests.
+- [Security] Apply security patch [26112](https://github.com/openedx/edx-platform/pull/26112).
+- [Bugfix] Fix `local exec` command which crashed with a `AttributeError`.
+
+## v11.1.0 (2021-01-13)
+
+- [Bugfix] Fix "Read-only file system" errors when running `tutor dev runserver` commands on Mac OS (again, see #392).
+- [Feature] Automatically bind-mount volumes from the `volumes/` directory with the `--volume=/...` syntax.
+
+## v11.0.7 (2021-01-11)
+
+- [Security] Apply security patch [26029](https://github.com/openedx/edx-platform/pull/26029).
+
+## v11.0.6 (2021-01-05)
+
+- [Security] Apply security patch [25974](https://github.com/openedx/edx-platform/pull/25974).
+
+## v11.0.5 (2020-12-30)
+
+- [Bugfix] Fix "Invalid type for parameter ContentType" error on js upload in Scorm xblock ([openedx-scorm-xblock #16](https://github.com/overhangio/openedx-scorm-xblock/issues/16)).
## v11.0.4 (2020-12-17)
-- [Bugfix] Fix "Read-only file system" errors when running `tutor dev runserver` commands on Mac OS. (#392)
+- [Bugfix] Fix "Read-only file system" errors when running `tutor dev runserver` commands on Mac OS (#392).
## v11.0.3 (2020-12-15)
-- [Bugfix] Fix upload of video transcripts to S3 (again)
+- [Bugfix] Fix upload of video transcripts to S3 (again).
## v11.0.2 (2020-12-12)
-- [Bugfix] Fix missing celery tasks from edx-platform (see [upstream PR](https://github.com/edx/edx-platform/pull/25840))
+- [Bugfix] Fix missing celery tasks from edx-platform (see [upstream PR](https://github.com/openedx/edx-platform/pull/25840)).
## v11.0.1 (2020-12-10)
-- [Security] Apply security patch [25834](https://github.com/edx/edx-platform/pull/25834)
-- [Bugfix] Fix Android apk directory mount path
+- [Security] Apply security patch [25834](https://github.com/openedx/edx-platform/pull/25834).
+- [Bugfix] Fix Android apk directory mount path.
## v11.0.0 (2020-12-09)
-- π₯[Improvement] Upgrade Open edX to Koa
+- π₯[Improvement] Upgrade Open edX to Koa.
- π₯ Setting changes:
- The ``ACTIVATE_HTTPS`` setting was renamed to ``ENABLE_HTTPS``.
- Other ``ACTIVATE_*`` variables were all renamed to ``RUN_*``.
@@ -31,33 +872,33 @@ Note: Breaking changes between versions are indicated by "π₯".
- The ``NGINX_HTTPS_PORT`` setting is deprecated.
- Architectural changes:
- Use Caddy as a web proxy for automated SSL/TLS certificate generation:
- - Nginx no longer listens to port 443 for https traffic
+ - Nginx no longer listens to port 443 for HTTPS traffic.
- The Caddy configuration file comes with a new ``caddyfile`` patch for much simpler SSL/TLS management.
- Configuration files for web proxies are no longer provided.
- Kubernetes deployment no longer requires setting up a custom Ingress resource or custom manager.
- - Gunicorn and Whitenoise are replaced by uwsgi: this increases boostrap performance and makes it no longer necessary to mount media folders in the Nginx container.
- - Replace memcached and rabbitmq by redis.
+ - Gunicorn and Whitenoise are replaced with uwsgi: this increases bootstrap performance and makes it no longer necessary to mount media folders in the Nginx container.
+ - Replace Memcached and RabbitMQ with Redis.
- Additional features:
- Make it possible to disable all plugins at once with ``plugins disable all``.
- - Add ``tutor k8s wait`` command to wait for a pod to become ready
- - Faster, more reliable static assets with local memory caching
+ - Add ``tutor k8s wait`` command to wait for a pod to become ready.
+ - Faster, more reliable static assets with local memory caching.
- Deprecation: proxy files for Apache and Nginx are no longer provided out of the box.
- Removed plugin `{{ patch (...) }}` statements:
- "https-create", "k8s-ingress-rules", "k8s-ingress-tls-hosts": these are no longer necessary. Instead, declare your app in the "caddyfile" patch.
- - "local-docker-compose-nginx-volumes": this patch was primarily used to serve media assets. The recommended is now to serve assets with uwsgi.
+ - "local-docker-compose-nginx-volumes": this patch was primarily used to serve media assets. The recommended solution is now to serve assets with uwsgi.
## v10.5.3 (2020-12-09)
-- [Security] Apply upstream edx-platform [security patch](https://github.com/edx/edx-platform/pull/25782)
+- [Security] Apply upstream edx-platform [security patch](https://github.com/openedx/edx-platform/pull/25782).
## v10.5.2 (2020-12-07)
-- [Improvement] Increase the timeout of the gunicorn worker command in openedx Dockerfile
+- [Improvement] Increase the timeout of the gunicorn worker command in openedx Dockerfile.
## v10.5.1 (2020-11-30)
-- [Bugfix] Fix Dockerfile parsing on Windows
-- [Improvement] Add option to patch lms and cms nginx server blocks
+- [Bugfix] Fix Dockerfile parsing on Windows.
+- [Improvement] Add option to patch lms and cms Nginx server blocks.
## v10.5.0 (2020-11-19)
@@ -66,11 +907,11 @@ Note: Breaking changes between versions are indicated by "π₯".
- π₯[Improvement] Remove the undocumented `local run_hook` command. Instead, run `local init --limit=...`.
- π₯[Improvement] Remove `tutor android pullimage` command. Instead, run `tutor images pull android`.
- [Bugfix] Fix `config save` on Windows.
-- [Bugfix] Fix platform checking in user ID function
+- [Bugfix] Fix platform checking in user ID function.
## v10.4.1 (2020-11-11)
-- [Bugfix] Fix dependency error during `pip install tutor` due to urllib3 incompatibility
+- [Bugfix] Fix dependency error during `pip install tutor` due to urllib3 incompatibility.
- [Bugfix] Fix user ID checking under Windows.
- [Bugfix] Fix template rendering for Windows users.
- [Improvement] Switch to `bcrypt` for htpasswd password generation, for better portability on Windows.
@@ -82,536 +923,536 @@ Note: Breaking changes between versions are indicated by "π₯".
curl -fsSL https://overhang.io/tutor/ami/upgrade.sh | sh
-- [Improvement] Mount config and setting files in read-only mode
+- [Improvement] Mount config and setting files in read-only mode.
- π₯[Improvement] Enable unit completion tracking by default.
-- [Bugfix] Run `apt update` before `apt install` when installing deps in the openedx Dockerfile
+- [Bugfix] Run `apt update` before `apt install` when installing deps in the openedx Dockerfile.
## v10.3.1 (2020-10-16)
-- [Improvement] Make all commands considerably faster
-- [Improvement] Make it easier to override Mongodb connection parameters
-- [Bugfix] Add support for .woff and .woff2 font files in themes (thanks @mrtndwrd!)
+- [Improvement] Make all commands considerably faster.
+- [Improvement] Make it easier to override Mongodb connection parameters.
+- [Bugfix] Add support for .woff and .woff2 font files in themes (thanks @mrtndwrd!).
## v10.3.0 (2020-10-13)
-- π₯[Improvement] Simplify CORS configuration
+- π₯[Improvement] Simplify CORS configuration.
## v10.2.4 (2020-10-06)
-- [Bugfix] Fix Apache proxy configuration when HTTPS is enabled (#370)
+- [Bugfix] Fix Apache proxy configuration when HTTPS is enabled (#370).
## v10.2.3 (2020-10-02)
-- [Feature] Add ``images printtag`` command
-- [Improvement] Make it possible to override individual contact email addresses with plugins
-- [Bugfix] Replace "no-reply@LMS_BASE" email address by regular contact email address
-- [Bugfix] Disable learner records globally by default
-- [Improvement] Upgrade to the latest release of MySQL 5.6
-- [Improvement] Non-plugin settings added by "set" directives are now automatically removed when the plugin is disabled (#241)
+- [Feature] Add ``images printtag`` command.
+- [Improvement] Make it possible to override individual contact email addresses with plugins.
+- [Bugfix] Replace "no-reply@LMS_BASE" email address by regular contact email address.
+- [Bugfix] Disable learner records globally by default.
+- [Improvement] Upgrade to the latest release of MySQL 5.6.
+- [Improvement] Non-plugin settings added by "set" directives are now automatically removed when the plugin is disabled (#241).
## v10.2.2 (2020-09-05)
-- [Improvement] Add CORS basic configuration to LMS for subdomains of the LMS
-- [Feature] Add support for `images build --add-host` option (thanks @grinderz!)
-- [Bugfix] Fix podman compatibility by replacing `docker-compose rm` command by `docker-compose stop` when stopping containers
-- [Improvement] Improve plugin data deletion
-- [Improvement] Introduce the `OPENEDX_COMMON_VERSION` setting
-- [Bugfix] Make it possible to run init jobs without starting the entire platform
-- [Improvement] Reduce "openedx" Docker image size with static asset de-duplication
+- [Improvement] Add CORS basic configuration to LMS for subdomains of the LMS.
+- [Feature] Add support for `images build --add-host` option (thanks @grinderz!).
+- [Bugfix] Fix podman compatibility by replacing `docker-compose rm` command with `docker-compose stop` when stopping containers.
+- [Improvement] Improve plugin data deletion.
+- [Improvement] Introduce the `OPENEDX_COMMON_VERSION` setting.
+- [Bugfix] Make it possible to run init jobs without starting the entire platform.
+- [Improvement] Reduce "openedx" Docker image size with static asset de-duplication.
## v10.2.1 (2020-08-27)
-- [Bugfix] Upgrade all services to open-release/juniper.3
-- [Bugfix] Fix upload of video transcripts to S3
-- [Improvement] Memorize whether the user is running a production platform during interactive configuration
+- [Bugfix] Upgrade all services to open-release/juniper.3.
+- [Bugfix] Fix upload of video transcripts to S3.
+- [Improvement] Memorize whether the user is running a production platform during interactive configuration.
## v10.2.0 (2020-08-16)
-- [Bugfix] Fix incorrect loading of some resources from localhost:18000 in development
-- [Bugfix] Fix Samesite=None Secure=False cookie error for users accessing the LMS with the latest release of Google Chrome
-- [Security] Apply javascript security patch ([pull request](https://github.com/edx/edx-platform/pull/24762))
-- [Bugfix] Fix "FileError" on Scorm package upload in Scorm XBlock
-- π₯[Improvement] Serve openedx static assets with [whitenoise](http://whitenoise.evans.io/en/stable/) instead of nginx. This removes the `k8s-deployments-nginx-init-containers` patch. Plugins are encouraged to implement static asset serving with Whitenoise as well.
-- [Bugfix] Fix dependency on mysql service when mysql is not activated
-- [Improvement] Improve openedx Docker image build time and size with multi-stage build
-- π₯[Feature] Get rid of outdated sysadmin dashboard in LMS at /sysadmin
+- [Bugfix] Fix incorrect loading of some resources from localhost:18000 in development.
+- [Bugfix] Fix Samesite=None Secure=False cookie error for users accessing the LMS with the latest release of Google Chrome.
+- [Security] Apply javascript security patch ([pull request](https://github.com/openedx/edx-platform/pull/24762)).
+- [Bugfix] Fix "FileError" on Scorm package upload in Scorm XBlock.
+- π₯[Improvement] Serve openedx static assets with [whitenoise](http://whitenoise.evans.io/en/stable/) instead of Nginx. This removes the `k8s-deployments-nginx-init-containers` patch. Plugins are encouraged to implement static asset serving with Whitenoise as well.
+- [Bugfix] Fix dependency on MySQL service when MySQL is not activated.
+- [Improvement] Improve openedx Docker image build time and size with the multi-stage build.
+- π₯[Feature] Get rid of outdated sysadmin dashboard in LMS at /sysadmin.
## v10.1.0 (2020-07-23)
-- [Security] Apply edx-platform upstream xss security fixes ([pull request](https://github.com/edx/edx-platform/pull/24568))
+- [Security] Apply edx-platform upstream xss security fixes ([pull request](https://github.com/openedx/edx-platform/pull/24568)).
- π₯[Feature] Make it possible to override the docker registry for just a few services by setting `DOCKER_IMAGE_SERVICENAME` values.
## v10.0.11 (2020-07-16)
-- [Feature] Upgrade all repositories to open-release/juniper.3
-- [Bugfix] Fix `reload-gunicorn` command
-- [Feature] Enable sysadmin dashboard in LMS at /sysadmin
+- [Feature] Upgrade all repositories to open-release/juniper.3.
+- [Bugfix] Fix `reload-gunicorn` command.
+- [Feature] Enable sysadmin dashboard in LMS at /sysadmin.
## v10.0.10 (2020-07-01)
-- [Bugfix] Fix pycontracts installation error when building openedx Docker image
-- [Bugfix] Fix access to dicussion forum in development mode
+- [Bugfix] Fix pycontracts installation error when building openedx Docker image.
+- [Bugfix] Fix access to the discussion forum in development mode.
## v10.0.9 (2020-07-01)
-- [Bugfix] Share grade download settings between the LMS and the CMS
+- [Bugfix] Share grade download settings between the LMS and the CMS.
## v10.0.8 (2020-06-23)
-- [Bugfix] Fix android user creation during init
-- [Bugfix] Fix undefined settings in k8s scripts, such as `createuser`
+- [Bugfix] Fix android user creation during init.
+- [Bugfix] Fix undefined settings in k8s scripts, such as `createuser`.
## v10.0.7 (2020-06-22)
-- [Bugfix] Fix TypeError on viewing xblock
-- [Bugfix] Fix authentication in Android mobile application
+- [Bugfix] Fix TypeError on viewing xblock.
+- [Bugfix] Fix authentication in Android mobile application.
## v10.0.6 (2020-06-22)
-- [Bugfix] Fix unsent activation emails and other asynchronous tasks
+- [Bugfix] Fix unsent activation emails and other asynchronous tasks.
## v10.0.5 (2020-06-21)
-- [Security] Apply edx-platform upstream xss security fixes ([pull request](https://github.com/edx/edx-platform/pull/24258))
+- [Security] Apply edx-platform upstream xss security fixes ([pull request](https://github.com/openedx/edx-platform/pull/24258)).
## v10.0.4 (2020-06-19)
-- [Bugfix] Fix broken `tutor ui` command in binary
+- [Bugfix] Fix broken `tutor ui` command in binary.
## v10.0.3 (2020-06-19)
-- [Bugfix] Fix error on android user creation
+- [Bugfix] Fix error on android user creation.
## v10.0.2 (2020-06-17)
-- [Bugfix] Fix crash when viewing problem in LMS
-- [Bugfix] Fix missing webpack-stats.json in openedx Docker image
+- [Bugfix] Fix crash when viewing the problem in LMS.
+- [Bugfix] Fix missing webpack-stats.json in openedx Docker image.
## v10.0.1 (2020-06-15)
-- [Bugfix] Fix KeyError when running ``local quickstart`` for the first time
+- [Bugfix] Fix KeyError when running ``local quickstart`` for the first time.
## v10.0.0 (2020-06-15)
-- π₯[Improvement] Upgrade to Juniper πΎ
-- [Bugfix] Fix nginx resolver address to address container restarts
-- [Feature] Add `--limit=myplugin` option to `init` commands to limit execution of initialisation to certain services and plugins
+- π₯[Improvement] Upgrade to Juniper πΎ.
+- [Bugfix] Fix Nginx resolver address to address container restarts.
+- [Feature] Add `--limit=myplugin` option to `init` commands to limit the execution of initialisation to certain services and plugins.
## v3.12.6 (2020-06-01)
-- [Improvement] Add `dig`, `ping` utilities to openedx-dev Docker image
-- [Bugfix] Resolve "Can't connect to MySQL server" on init
-- [Improvement] Make it possible to customize the MySQL root username, for connecting to external MySQL databases
+- [Improvement] Add `dig`, `ping` utilities to openedx-dev Docker image.
+- [Bugfix] Resolve "Can't connect to MySQL server" on init.
+- [Improvement] Make it possible to customise the MySQL root username, for connecting to external MySQL databases.
## v3.12.5 (2020-05-20)
-- [Improvement] Upgrade Android app to v2.21.1 and enable many features, such as downloading videos to SD card. Thanks for the help @ejklock!
-- [Bugfix] Fix Android app crash when accessing course
+- [Improvement] Upgrade Android app to v2.21.1 and enable many features, such as downloading videos to SD card. Thanks for the help @ejklock!.
+- [Bugfix] Fix Android app crash when accessing the course.
## v3.12.4 (2020-05-18)
-- [Improvement] Add ability to rescore SCORM units
-- [Bugfix] Fix scoring of graded SCORM units
+- [Improvement] Add ability to rescore SCORM units.
+- [Bugfix] Fix scoring of graded SCORM units.
- [Improvement] Increase maximum uploaded file size in the CMS from 10 to 100 Mb.
## v3.12.3 (2020-05-05)
-- [Security] Apply most recent edx-platform [security patches](https://discuss.openedx.org/t/security-patch-for-edit-chapter-xss-lint-issues/2030)
+- [Security] Apply most recent edx-platform [security patches](https://discuss.openedx.org/t/security-patch-for-edit-chapter-xss-lint-issues/2030).
## v3.12.2 (2020-04-29)
-- [Bugfix] Fix oauth2 authentication with 3rd-party services, such as discovery
-- [Bugfix] Upgrade scorm xblock to solve caching issue
+- [Bugfix] Fix oauth2 authentication with 3rd-party services, such as discovery.
+- [Bugfix] Upgrade scorm xblock to solve caching issue.
## v3.12.1 (2020-04-27)
-- [Improvement] Increase max upload allowed size to 250Mb in CMS
+- [Improvement] Increase max upload allowed size to 250Mb in CMS.
## v3.12.0 (2020-04-26)
-- π₯[Improvement] Do not deploy an ingress or SSL/TLS certificate issuer ressource by default in Kubernetes
-- [Improvement] Fix tls certificate generation in k8s
+- π₯[Improvement] Do not deploy an ingress or SSL/TLS certificate issuer resource by default in Kubernetes.
+- [Improvement] Fix tls certificate generation in k8s.
- π₯[Improvement] Radically change the way jobs are run: we no longer "exec", but instead run a dedicated container.
-- π₯[Improvement] Upgrade k8s certificate issuer to cert-manager.io/v1alpha2
-- [Feature] Add SCORM XBlock to default openedx docker image
+- π₯[Improvement] Upgrade k8s certificate issuer to cert-manager.io/v1alpha2.
+- [Feature] Add SCORM XBlock to default openedx docker image.
## v3.11.12 (2020-04-16)
-- [Feature] Make it easy to add custom translation strings to the openedx Docker image
-- [Improvement] Make it possible to rely on a different npm registry for faster image building
+- [Feature] Make it easy to add custom translation strings to the openedx Docker image.
+- [Improvement] Make it possible to rely on a different npm registry for faster image building.
## v3.11.11 (2020-04-15)
-- [Bugfix] Make sure all emails (including "password reset") are properly saved to a local file in development mode (#315)
-- [Improvement] Add `openedx-development-settings` patch to patch the LMS and the CMS simultaneously in development
-- [Bugfix] Fix missing celery tasks in the CMS
+- [Bugfix] Make sure all emails (including "password reset") are properly saved to a local file in development mode (#315).
+- [Improvement] Add `openedx-development-settings` patch to patch the LMS and the CMS simultaneously in development.
+- [Bugfix] Fix missing celery tasks in the CMS.
## v3.11.10 (2020-04-14)
-- [Bugfix] Fix updates to the course structure in the LMS (#302)
+- [Bugfix] Fix updates to the course structure in the LMS (#302).
## v3.11.9 (2020-04-07)
-- [Bugfix] Fix Android app build for domain names that include a dash ("-")
+- [Bugfix] Fix Android app build for domain names that include a dash ("-").
## v3.11.8 (2020-04-06)
-- [Feature] Add `encrypt` template filter to conveniently add htpasswd-based authentication to nginx
-- [Bugfix] Fix "missing tty" during init in cron jobs
+- [Feature] Add `encrypt` template filter to conveniently add htpasswd-based authentication to Nginx.
+- [Bugfix] Fix "missing tty" during init in cron jobs.
## v3.11.7 (2020-04-01)
-- [Bugfix] Fix missing js translations
-- [Bugfix] Fix tls certificate generation in cron jobs
+- [Bugfix] Fix missing js translations.
+- [Bugfix] Fix tls certificate generation in cron jobs.
## v3.11.6 (2020-03-13)
-- [Bugfix] Fix "Unable to resolve dependency" error during forum initialisation
-- [Feature] Add `settheme` command to easily assign a theme to a domain name
-- [Improvement] Modify nginx access logs to include request scheme and server name (plugin developers should use the "tutor" log format)
-- [Bugfix] Fix DNS resolution of restarted service
-- [Feature] Restart multiple services with `local restart`
-- [Feature] Make it possible to easily reload openedx gunicorn process with `tutor local exec lms reload-gunicorn`
-- [Improvement] Rename lms/cms_worker to lms/cms-worker in local deployment
-- [Improvement] Add the management plugin to the rabbitmq container
-- [Improvement] Make it possible to run an Elasticsearch service on https
+- [Bugfix] Fix "Unable to resolve dependency" error during forum initialisation.
+- [Feature] Add `settheme` command to easily assign a theme to a domain name.
+- [Improvement] Modify Nginx access logs to include request scheme and server name (plugin developers should use the "tutor" log format).
+- [Bugfix] Fix DNS resolution of restarted service.
+- [Feature] Restart multiple services with `local restart`.
+- [Feature] Make it possible to easily reload the openedx gunicorn process with `tutor local exec lms reload-gunicorn`.
+- [Improvement] Rename lms/cms_worker to lms/cms-worker in local deployment.
+- [Improvement] Add the management plugin to the RabbitMQ container.
+- [Improvement] Make it possible to run an Elasticsearch service on HTTPS.
## v3.11.5 (2020-02-27)
-- [Improvement] Switch edx-platform from open-release/ironwood.2 tag to the open-release/ironwood.master branch
-- [Security] Upgrade django to 1.11.28
-- [Improvement] Make it possible to configure the elasticsearch heap size
-- [Bugfix] Fix broken elasticsearch environment variables
+- [Improvement] Switch edx-platform from open-release/ironwood.2 tag to the open-release/ironwood.master branch.
+- [Security] Upgrade django to 1.11.28.
+- [Improvement] Make it possible to configure the Elasticsearch heap size.
+- [Bugfix] Fix broken Elasticsearch environment variables.
- [Improvement] Restore more recent Android app version (#289).
## v3.11.4 (2020-02-16)
-- [Bugfix] Fix auth problem in Android app (#289)
+- [Bugfix] Fix auth problem in Android app (#289).
-## 3.11.3 (2020-01-21)
+## v3.11.3 (2020-01-21)
-- [Bugfix] Fix incorrectly parsed empty strings for `config save --set ...=...` commands
+- [Bugfix] Fix incorrectly parsed empty strings for `config save --set ...=...` commands.
-## 3.11.2 (2020-01-17)
+## v3.11.2 (2020-01-17)
-- [Bugfix] Make sure `docker-compose.override.yml` are loaded in dev and local contexts
+- [Bugfix] Make sure `docker-compose.override.yml` is loaded in dev and local contexts.
-## 3.11.1 (2020-01-16)
+## v3.11.1 (2020-01-16)
-- [Feature] Add `config render` command
+- [Feature] Add `config render` command.
-## 3.11.0 (2020-01-14)
+## v3.11.0 (2020-01-14)
-- [Feature] Add support for simple, YAML-based plugins
-- π₯[Improvement] The output of `plugins list` now includes plugin version numbers
+- [Feature] Add support for simple, YAML-based plugins.
+- π₯[Improvement] The output of `plugins list` now includes plugin version numbers.
-## 3.10.1 (2020-01-13)
+## v3.10.1 (2020-01-13)
-- [Improvement] Explicitely point to docker.io images, when necessary, for [podman](https://podman.io/) compatibility
+- [Improvement] Explicitly point to docker.io images, when necessary, for [podman](https://podman.io/) compatibility.
-## 3.10.0 (2020-01-10)
+## v3.10.0 (2020-01-10)
-- [Bugfix] Fix oauth authentication in dev mode
-- [Improvement] Upgrade to the 3.7 docker-compose syntax
-- [Improvement] The `dev runserver` command can now be run for just any service
-- π₯[Feature] `dev run/exec` commands now support generic options which are passed to docker-compose. Consequently, defining the `TUTOR_EDX_PLATFORM_PATH` environment variable no longer works. Instead, users are encouraged to explicitely pass the `-v` option, define a command alias or create a `docker-compose.override.yml` file.
+- [Bugfix] Fix OAuth authentication in dev mode.
+- [Improvement] Upgrade to the 3.7 docker-compose syntax.
+- [Improvement] The `dev runserver` command can now be run for just any service.
+- π₯[Feature] `dev run/exec` commands now support generic options which are passed to docker-compose. Consequently, defining the `TUTOR_EDX_PLATFORM_PATH` environment variable no longer works. Instead, users are encouraged to explicitly pass the `-v` option, define a command alias or create a `docker-compose.override.yml` file.
-## 3.9.1 (2020-01-08)
+## v3.9.1 (2020-01-08)
-- [Improvement] Make it possible to override the project name in development mode
-- [Bugfix] Fix user switching in development mode
-- [Bugfix] Fix "k8s quickstart" crash
+- [Improvement] Make it possible to override the project name in development mode.
+- [Bugfix] Fix user switching in development mode.
+- [Bugfix] Fix "k8s quickstart" crash.
-## 3.9.0 (2019-12-21)
+## v3.9.0 (2019-12-21)
-- [Security] Apply django 1.11.21 -> 1.11.27 security patches
-- [Bugfix] Fix running dev image with `sudo`
-- [Improvement] Add `cms/lms-env-features` patches (#276)
-- [Feature] Add plugin subcommands
-- π₯[Improvement] Move ``-r/--root`` option to parent command level
-- [Bugfix] Fix course about page visibility
-- [Improvement] Print gunicorn access logs in the console
-- π₯[Improvement] Get rid of the `indexcourses` and `portainer` command (#269)
+- [Security] Apply django 1.11.21 -> 1.11.27 security patches.
+- [Bugfix] Fix running dev image with `sudo`.
+- [Improvement] Add `cms/lms-env-features` patches (#276).
+- [Feature] Add plugin subcommands.
+- π₯[Improvement] Move ``-r/--root`` option to parent command level.
+- [Bugfix] Fix course about page visibility.
+- [Improvement] Print gunicorn access logs in the console.
+- π₯[Improvement] Get rid of the `indexcourses` and `portainer` command (#269).
-## 3.8.0 (2019-11-22)
+## v3.8.0 (2019-11-22)
-- [Improvement] Add `k8s-deployments-nginx-volume-mounts` patch
-- [Bugfix] Fix running forum locally when both elasticsearch and mongodb are not activated (#266)
-- [Bugfix] Fix MongoDb url in forum when running separate service (#267)
+- [Improvement] Add `k8s-deployments-nginx-volume-mounts` patch.
+- [Bugfix] Fix running forum locally when both Elasticsearch and MongoDB are not activated (#266).
+- [Bugfix] Fix MongoDB URL in the forum when running a separate service (#267).
- π₯[Improvement] Better `dev` commands, with dedicated development docker image. One of the consequences is that the `dev watchthemes` command is replaced by `dev run lms watchthemes`.
-- [Improvement] `images` commands now accept multiple `image` arguments
+- [Improvement] `images` commands now accept multiple `image` arguments.
-## 3.7.4 (2019-10-19)
+## v3.7.4 (2019-10-19)
-- [Bugfix] Fix missing requirements file in pypi package (#261)
-- [Improvement] Add missing cms/lms production/development setting patches
-- [Improvement] Allow SigV4 authentication for video upload to S3
-- [Bugfix] Fix cms development settings
+- [Bugfix] Fix missing requirements file in PyPI package (#261).
+- [Improvement] Add missing cms/lms production/development setting patches.
+- [Improvement] Allow SigV4 authentication for video upload to S3.
+- [Bugfix] Fix cms development settings.
-## 3.7.3 (2019-10-17)
+## v3.7.3 (2019-10-17)
-- [Improvement] Upgrade openedx locales to Ironwood
+- [Improvement] Upgrade openedx locales to Ironwood.
-## 3.7.2 (2019-10-09)
+## v3.7.2 (2019-10-09)
-- [Improvement] Properly set studio title (#246)
-- [Improvement] Enable Mysql strict mode
+- [Improvement] Properly set studio title (#246).
+- [Improvement] Enable Mysql strict mode.
-## 3.7.1 (2019-10-06)
+## v3.7.1 (2019-10-06)
-- [Feature] Introduce tutor docker image
+- [Feature] Introduce tutor docker image.
- [Feature] Introduce `local hook` command for plugin development.
-- [Bugfix] Persist `private.txt` file between two runs of `config save`. (#247)
+- [Bugfix] Persist `private.txt` file between two runs of `config save` (#247).
- [Improvement] Added configuration values to limit the number of gunicorn workers for the LMS and CMS.
-## 3.7.0 (2019-09-03)
+## v3.7.0 (2019-09-03)
-- π₯[Improvement] Get rid of mysql-client container
-- [Improvement] Add "local-docker-compose-lms/cms-dependencies" plugin patches
-- [Improvement] Use "exec" instead of "run" to initialise local platform
+- π₯[Improvement] Get rid of mysql-client container.
+- [Improvement] Add "local-docker-compose-lms/cms-dependencies" plugin patches.
+- [Improvement] Use "exec" instead of "run" to initialise local platform.
-## 3.6.3 (2019-08-31)
+## v3.6.3 (2019-08-31)
-- [Security] Fix CustomTagModule mako template injection
-- [Improvement] Move all plugins outside of the tutor repo
-- [Bugfix/Improvement] Add all plugins (with data) into binary bundle (#242)
+- [Security] Fix CustomTagModule mako template injection.
+- [Improvement] Move all plugins outside of the tutor repo.
+- [Bugfix/Improvement] Add all plugins (with data) into binary bundle (#242).
-## 3.6.2 (2019-08-07)
+## v3.6.2 (2019-08-07)
-- [Bugfix] Fix missing templates in bundled plugins
-- [Bugfix] Enable html certificate view
+- [Bugfix] Fix missing templates in bundled plugins.
+- [Bugfix] Enable HTML certificate view.
-## 3.6.1 (2019-07-27)
+## v3.6.1 (2019-07-27)
-- [Bugfix] Fix missing patches from minio plugin (thanks @Wejie!)
+- [Bugfix] Fix missing patches from minio plugin (thanks @Wejie!).
-## 3.6.0 (2019-07-11)
+## v3.6.0 (2019-07-11)
-- [Feature] Modify ``createuser`` commands to define a password from the command line
-- [Improvement] Better yaml value parsing from command line
-- [Feature] Add `dev exec` command
-- [Bugfix] Fix incorrect notes settings definition
-- [Improvement] Make it possible to start/stop/reboot a selection of services
-- [Improvement] Add `local/k8s reboot` commands
-- [Improvement] Add `-U/--unset` option to `config save`
-- [Bugfix] Fix insecure static asset loading when web proxy is enabled
-- [Improvement] Rename `SECRET_KEY` configuration parameter to `OPENEDX_SECRET_KEY`
-- [Improvement] Add support for SSL and TLS in external SMTP server (#231)
-- [Bugfix] Fix missing video transcripts in LMS (#229)
-- [Improvement] Make it possible to enable/disable multiple plugins at once
-- [Improvement] Add a few local and k8s patches for plugins
+- [Feature] Modify ``createuser`` commands to define a password from the command line.
+- [Improvement] Better YAML value parsing from the command line.
+- [Feature] Add `dev exec` command.
+- [Bugfix] Fix incorrect notes settings definition.
+- [Improvement] Make it possible to start/stop/reboot a selection of services.
+- [Improvement] Add `local/k8s reboot` commands.
+- [Improvement] Add `-U/--unset` option to `config save`.
+- [Bugfix] Fix insecure static asset loading when web proxy is enabled.
+- [Improvement] Rename `SECRET_KEY` configuration parameter to `OPENEDX_SECRET_KEY`.
+- [Improvement] Add support for SSL and TLS in external SMTP server (#231).
+- [Bugfix] Fix missing video transcripts in LMS (#229).
+- [Improvement] Make it possible to enable/disable multiple plugins at once.
+- [Improvement] Add a few local and k8s patches for plugins.
-## 3.5.3 (2019-07-05)
+## v3.5.3 (2019-07-05)
-- [Bugfix] Add pre-init hook for correct initialisation of minio
+- [Bugfix] Add pre-init hook for correct initialisation of minio.
-## 3.5.2 (2019-07-05)
+## v3.5.2 (2019-07-05)
-- [Security] Apply certificate XSS security patch
+- [Security] Apply certificate XSS security patch.
-## 3.5.1 (2019-07-04)
+## v3.5.1 (2019-07-04)
-- [Feature] Make it possible for plugins to patch the build templates
-- [Improvement] Move Xqueue and Student notes to a dedicated plugin
+- [Feature] Make it possible for plugins to patch the build templates.
+- [Improvement] Move Xqueue and Student notes to a dedicated plugin.
-## 3.4.3 (2019-06-24)
+## v3.4.3 (2019-06-24)
-- [Bugfix] Fix missing password values from generated configuration
+- [Bugfix] Fix missing password values from generated configuration.
-## 3.4.2 (2019-06-23)
+## v3.4.2 (2019-06-23)
-- [Bugfix] Fix incorrect settings during lms/cms init (#224)
+- [Bugfix] Fix incorrect settings during lms/cms init (#224).
-## 3.4.1 (2019-06-23)
+## v3.4.1 (2019-06-23)
-- [Bugfix] Fix install from pypi
-- [Improvement] Get rid of kubernetes python package dependency
+- [Bugfix] Fix install from PyPI.
+- [Improvement] Get rid of Kubernetes python package dependency.
-## 3.4.0 (2019-06-17)
+## v3.4.0 (2019-06-17)
-- [Feature] Creation of a plugin system
-- [Feature] Kubernetes support out of beta
-- [Improvement] Switch to pinned image tags for easier upgrades
+- [Feature] Creation of a plugin system.
+- [Feature] Kubernetes support out of beta.
+- [Improvement] Switch to pinned image tags for easier upgrades.
- π₯[Improvement] Remove the `-y/--yes` option: `tutor config save` is now non-interactive by default. Use `-i/--interactive` to force interactive mode.
-- π₯[Improvement] Replace the `databases` command by `init`.
-- [Improvement] Upgrade to ironwood.2
-- [Improvement] Add `-y/--yes` option to `local quickstart` for non-interactive quickstart
-- [Improvement] Persist LMS/CMS logs to disk by default (with collaboration from @silviot πͺ)
-- [Bugfix] Fix installing a locally cloned requirement repository
-- [Improvement] Add `--no-cache` option to `images build`
-- [Improvement] Make it possible to configure the notes service hostname
-- [Improvement] Better, more robust MySQL initialisation
+- π₯[Improvement] Replace the `databases` command with `init`.
+- [Improvement] Upgrade to ironwood.2.
+- [Improvement] Add `-y/--yes` option to `local quickstart` for non-interactive quickstart.
+- [Improvement] Persist LMS/CMS logs to disk by default (with collaboration from @silviot πͺ).
+- [Bugfix] Fix installing a locally cloned requirement repository.
+- [Improvement] Add `--no-cache` option to `images build`.
+- [Improvement] Make it possible to configure the notes service hostname.
+- [Improvement] Better, more robust MySQL initialisation.
-## 3.3.10 (2019-05-15)
+## v3.3.10 (2019-05-15)
-- [Bugfix] Fix boolean configuration choices
+- [Bugfix] Fix boolean configuration choices.
-## 3.3.9 (2019-05-13)
-- [Improvement] Add `local exec` command for running commands inside existing containers
-- [Bugfix] Fix triple display of courses in LMS search (upstream patch, #189)
+## v3.3.9 (2019-05-13)
+- [Improvement] Add `local exec` command for running commands inside existing containers.
+- [Bugfix] Fix triple display of courses in LMS search (upstream patch, #189).
-## 3.3.8 (2019-04-28)
+## v3.3.8 (2019-04-28)
-- [Bugfix] Reduce the number of gunicorn workers to address RAM usage (#207)
+- [Bugfix] Reduce the number of gunicorn workers to address RAM usage (#207).
-## 3.3.7 (2019-04-28)
+## v3.3.7 (2019-04-28)
-- [Bugfix] Fix "Timeout after 20s" on running migrations
+- [Bugfix] Fix "Timeout after 20s" on running migrations.
-## 3.3.6 (2019-04-27)
+## v3.3.6 (2019-04-27)
-- [Bugfix] Fix KeyError on first quickstart
-- [Improvement] De-duplication of prod/dev settings. Thanks @silviot! πΊ
+- [Bugfix] Fix KeyError on the first quickstart.
+- [Improvement] De-duplication of prod/dev settings. Thanks, @silviot! πΊ.
-## 3.3.5 (2019-04-22)
+## v3.3.5 (2019-04-22)
-- [Feature] Pluggable LMS/CMS/forum
-- [Improvement] Safer environment overwrite. Thanks @silviot! π
-- [Security] Fix Jinja2 vulnerability
-- [Improvement] Improve CLI cold start performance
-- [Improvement] Allow uppercase "Y" and "N" as answers to boolean questions
+- [Feature] Pluggable LMS/CMS/forum.
+- [Improvement] Safer environment overwrite. Thanks, @silviot! π.
+- [Security] Fix Jinja2 vulnerability.
+- [Improvement] Improve CLI cold start performance.
+- [Improvement] Allow uppercase "Y" and "N" as answers to boolean questions.
-## 3.3.4 (2019-04-09)
+## v3.3.4 (2019-04-09)
-- [Improvement] Rename `--silent` option to `-y/--yes`
-- [Bugfix] Fix (again) login from studio when https is activated (#193)
+- [Improvement] Rename `--silent` option to `-y/--yes`.
+- [Bugfix] Fix (again) login from studio when HTTPS is activated (#193).
-## 3.3.3 (2019-03-29)
+## v3.3.3 (2019-03-29)
-- [Bugfix] Fix `pip install tutor-openedx`
+- [Bugfix] Fix `pip install tutor-openedx`.
-## 3.3.2 (2019-03-27)
+## v3.3.2 (2019-03-27)
-- [Bugfix] Fix login from localhost
-- [Bugfix] Fix Android app image build
+- [Bugfix] Fix login from localhost.
+- [Bugfix] Fix Android app image build.
-## 3.3.1 (2019-03-25)
+## v3.3.1 (2019-03-25)
-- [Improvement] Improve assets building for development
-- [Improvement] Support CMS login when the CMS is not a subdomain of the LMS
+- [Improvement] Improve assets building for development.
+- [Improvement] Support CMS login when the CMS is not a subdomain of the LMS.
-## 3.3.0 (2019-03-22)
+## v3.3.0 (2019-03-22)
-- [Feature] Upgrade from Hawthorn to Ironwood
+- [Feature] Upgrade from Hawthorn to Ironwood.
-## 3.2.2 (2019-03-21)
+## v3.2.2 (2019-03-21)
-- [Feature] Multiple platforms on a single server \o/
-- [Feature] Easily configure web proxy on the host
-- [Bugfix] Fix `images pull all` command which failed on "all" image
-- [Improvement] Add configurable mongodb, SMTP and rabbitmq authentication
-- [Improvement] Harmonize mysql username/password configuration parameters
-- [Feature] Configurable and pluggable data storage backends (#114)
+- [Feature] Multiple platforms on a single server \o/.
+- [Feature] Easily configure web proxy on the host.
+- [Bugfix] Fix `images pull all` command which failed on "all" image.
+- [Improvement] Add configurable MongoDB, SMTP and RabbitMQ authentication.
+- [Improvement] Harmonize MySQL username/password configuration parameters.
+- [Feature] Configurable and pluggable data storage backends (#114).
-## 3.2.1 (2019-03-19)
+## v3.2.1 (2019-03-19)
-- [Feature] Enable grade downloads by default (#143)
-- [Improvement] Remove orphan containers on `local start`
+- [Feature] Enable grade downloads by default (#143).
+- [Improvement] Remove orphan containers on `local start`.
-## 3.2.0 (2019-03-18)
+## v3.2.0 (2019-03-18)
-- [Improvement] `images pull` now also pulls vendor images
-- [Feature] Add convenient `config printvalue` command
-- [Feature] Customize docker registry
-- [Feature] Load configuration parameters from the system environment
-- [Improvement] Automatic environment re-generation after re-configuration
-- [Improvement] Error and interrupt handling in UI and web UI
-- [Bugfix] Fix missing webui env directory
+- [Improvement] `images pull` now also pulls vendor images.
+- [Feature] Add convenient `config printvalue` command.
+- [Feature] Customise docker registry.
+- [Feature] Load configuration parameters from the system environment.
+- [Improvement] Automatic environment re-generation after re-configuration.
+- [Improvement] Error and interrupt handling in UI and web UI.
+- [Bugfix] Fix missing webui env directory.
-## 3.1.0 (2019-03-09)
+## v3.1.0 (2019-03-09)
-- [Improvement] Install python requirements in virtual env in docker image
-- [Bugfix] Add missing volume for theme development
-- [Improvement] Rename "config [non]interactive" command to "config save [--silent]"
-- [Improvement] More explicit logging during environment generation
-- [Improvement] Configurable docker images (#122)
-- [Bugfix] Fix "android pullimage" command
-- [Improvement] Do not upgrade images as part of quickstart
-- [Bugfix] Fix USERID setup in development mode and various dev-related docs (#177)
+- [Improvement] Install python requirements in virtual env in docker image.
+- [Bugfix] Add missing volume for theme development.
+- [Improvement] Rename "config [non]interactive" command to "config save [--silent]".
+- [Improvement] More explicit logging during environment generation.
+- [Improvement] Configurable docker images (#122).
+- [Bugfix] Fix "android pullimage" command.
+- [Improvement] Do not upgrade images as part of quickstart.
+- [Bugfix] Fix USERID setup in development mode and various dev-related docs (#177).
-## 3.0.6 (2019-02-26)
+## v3.0.6 (2019-02-26)
-- [Bugfix] Fix import/export of demo course (#175)
+- [Bugfix] Fix import/export of demo course (#175).
-## 3.0.5 (2019-02-14)
+## v3.0.5 (2019-02-14)
-- [Feature] Add cloud deployment script
-- [Improvement] Run `images pull` command
-- [Improvement] Run `indexcourses` on importing demo course
-- [Improvement] Add `runserver stop` command
+- [Feature] Add cloud deployment script.
+- [Improvement] Run `images pull` command.
+- [Improvement] Run `indexcourses` on importing demo course.
+- [Improvement] Add `runserver stop` command.
-## 3.0.4 (2019-02-13)
+## v3.0.4 (2019-02-13)
-- [Minor] Minimum required `click` version is 7.0 (#171)
-- [Bugfix] Fix `runserver` dev command (#172)
-- [Minor] Fix non-https link to documentation in pypi
-- [Minor] Fix `createuser` documentation
+- [Minor] Minimum required `click` version is 7.0 (#171).
+- [Bugfix] Fix `runserver` dev command (#172).
+- [Minor] Fix non-https link to documentation in PyPI.
+- [Minor] Fix `createuser` documentation.
-## 3.0.3 (2019-02-12)
+## v3.0.3 (2019-02-12)
-- [Bugfix] Add missing template data to pypi package
-- [Bugfix] Fix quickstart on Kubernetes (#164)
-- [Improvement] Add datatases task to Kubernetes quickstart (#167)
+- [Bugfix] Add missing template data to the PyPI package.
+- [Bugfix] Fix quickstart on Kubernetes (#164).
+- [Improvement] Add databases task to Kubernetes quickstart (#167).
-## 3.0.2 (2019-02-12)
-
-- [Bugfix] Fix import paths -- π thanks @silviot!
-- [Bugfix] Properly set docker project name in mysql logs -- π¦ thanks again @silviot!
-
-## 3.0.1 (2019-02-11)
-
-- [Bugfix] fix mysql initialisation (#159, #160)
-- [Improvement] Better handling of continuous integration
-- [Bugfix] fix `tutor --version` (#156)
-- [Improvement] Absolute settings imports -- π― thanks @tonytan4ever!
-
-## 3.0.0 (2019-02-09)
-
-- [Improvement] Complete rewrite of Tutor: switch from a make-based project to a single binary which runs all commands.
-- [Feature] An web user interface can be created with `tutor webui start`
-- [Bugfix] Add missing elasticsearch to Kubernetes deployment (#147)
-- [Improvement] Upload `tutor-openedx` to pypi
-
-## Older changes
-
-- 2019-01-27 [Bugfix] Fix video transcript/srt upload and download of user-uploaded files. Thanks @dannielariola!
-- 2019-01-20 [Improvement] Make it easy to load custom settings for the local production install
-- 2019-01-19 [Improvement] Upgrade to Ironwood
-- 2019-01-16 [Improvement] Switch license from MIT to AGPL
-- 2019-01-04 [Bugfix] Fix xqueue consumer command
-- 2018-12-26 [Improvement] Upgrade nodejs to 5.5.1
-- 2018-12-07 [Improvement] Bundle theme and production static assets in the openedx docker image
-- 2018-12-02 [Feature] Download extra locales from [openedx-i18n](https://github.com/openedx/openedx-i18n/) to the Open edX Docker image
-- 2018-11-28 [Feature] Easily change openedx docker image
-- 2018-11-28 [Feature] Enable comprehensive theming!
-- 2018-11-28 [Improvement] Get rid of datadog
-- 2018-11-28 [Improvement] Upgrade docker images to ubuntu 18.04 for android, forum, notes, xqueue
-- 2018-11-28 [Feature] Make it possible to define default platform language interactively
-- 2018-11-26 [Improvement] Make it easier to run a forked version of edx-platform
-- 2018-11-25 [Feature] Use local filesystem for open assessment file upload
-- 2018-11-23 [Improvement] Faster container bootstrapping without "chmod", as suggested by @silviot
-- 2018-11-20 [Bugfix] Fix cross-platform theme assets generation
-- 2018-11-17 [Improvement] Custom nginx port mapping. :crossed_swords: @frob @frohro
-- 2018-11-17 [Improvement] Add "make restart-openedx" command. :+1: @frob
-- 2018-11-13 [Improvement] Facilitate install of extra XBlocks. Thanks @frob!
-- 2018-10-30 [Bugfix] Fix rabbitmq restart policy
-- 2018-10-03 [Improvement/Bugfix] Fix and accelerate Android application build
-- 2018-10-02 [Improvement] Bump Open edX version to hawthorn.2
-- 2018-09-30 [Bugfix] Fix CMS celery worker, including export tasks
-- 2018-09-30 [Improvement] Simplify boolean feature flags definition
-- 2018-09-29 [Improvement] Add logging commands
-- 2018-09-29 [Improvement] Add self-documented help with "make help"
-- 2018-09-29 [Feature] Add [Portainer](https://portainer.io) as an optional web UI to administer docker containers
-- 2018-09-15 [Feature] Add student notes as an optional feature
-- 2018-09-15 [Feature] Add templates to configurator container, which can now be run separately
-- 2018-09-15 [Improvement] Rename "up" and "daemon" commands to "run" and "daemonize"
-- 2018-09-15 [Feature] Activate course search and discovery
-- 2018-09-15 [Bugfix] Deduplicate console logs from lms/cms
-- 2018-09-05 [Improvement] Use a single email address for all inbound email
-- 2018-09-04 [Bugfix] Get make commands to work with 'sudo'
-- 2018-09-02 [Bugfix] Get HTTPS to work for CMS. Thanks @flytreeleft!
-- 2018-08-28 [Bugfix] Fix certbot image updating
-- 2018-08-27 [Improvement] Add development requirements to openedx image
-- 2018-08-27 [Bugfix] Upgrade mongodb
-- 2018-08-19 [Improvement] Make Xqueue an optional feature
-- 2018-08-16 [Feature] Add HTTPS support
+## v3.0.2 (2019-02-12)
+
+- [Bugfix] Fix import paths -- π thanks @silviot!.
+- [Bugfix] Properly set docker project name in MySQL logs -- π¦ thanks again @silviot!.
+
+## v3.0.1 (2019-02-11)
+
+- [Bugfix] fix MySQL initialisation (#159, #160).
+- [Improvement] Better handling of continuous integration.
+- [Bugfix] fix `tutor --version` (#156).
+- [Improvement] Absolute settings imports -- π― thanks @tonytan4ever!.
+
+## v3.0.0 (2019-02-09)
+
+- [Improvement] Complete rewrite of Tutor: switch from a make-based project to a single binary that runs all commands.
+- [Feature] An web user interface can be created with `tutor webui start`.
+- [Bugfix] Add missing Elasticsearch to Kubernetes deployment (#147).
+- [Improvement] Upload `tutor-openedx` to PyPI .
+
+## Older changes (< 3.0.0)
+
+- 2019-01-27 [Bugfix] Fix video transcript/srt upload and download of user-uploaded files. Thanks @dannielariola!.
+- 2019-01-20 [Improvement] Make it easy to load custom settings for the local production install.
+- 2019-01-19 [Improvement] Upgrade to Ironwood.
+- 2019-01-16 [Improvement] Switch license from MIT to AGPL.
+- 2019-01-04 [Bugfix] Fix xqueue consumer command.
+- 2018-12-26 [Improvement] Upgrade nodejs to 5.5.1.
+- 2018-12-07 [Improvement] Bundle theme and production static assets in the openedx docker image.
+- 2018-12-02 [Feature] Download extra locales from [openedx-i18n](https://github.com/openedx/openedx-i18n/) to the Open edX Docker image.
+- 2018-11-28 [Feature] Easily change openedx docker image.
+- 2018-11-28 [Feature] Enable comprehensive theming!.
+- 2018-11-28 [Improvement] Get rid of datadog.
+- 2018-11-28 [Improvement] Upgrade docker images to ubuntu 18.04 for android, forum, notes, xqueue.
+- 2018-11-28 [Feature] Make it possible to define default platform language interactively.
+- 2018-11-26 [Improvement] Make it easier to run a forked version of edx-platform.
+- 2018-11-25 [Feature] Use local filesystem for open assessment file upload.
+- 2018-11-23 [Improvement] Faster container bootstrapping without "chmod", as suggested by @silviot.
+- 2018-11-20 [Bugfix] Fix cross-platform theme assets generation.
+- 2018-11-17 [Improvement] Custom Nginx port mapping. :crossed_swords: @frob @frohro.
+- 2018-11-17 [Improvement] Add "make restart-openedx" command. :+1: @frob.
+- 2018-11-13 [Improvement] Facilitate install of extra XBlocks. Thanks @frob!.
+- 2018-10-30 [Bugfix] Fix RabbitMQ restart policy.
+- 2018-10-03 [Improvement/Bugfix] Fix and accelerate Android application build.
+- 2018-10-02 [Improvement] Bump Open edX version to hawthorn.2.
+- 2018-09-30 [Bugfix] Fix CMS celery worker, including export tasks.
+- 2018-09-30 [Improvement] Simplify boolean feature flags definition.
+- 2018-09-29 [Improvement] Add logging commands.
+- 2018-09-29 [Improvement] Add self-documented help with "make help".
+- 2018-09-29 [Feature] Add [Portainer](https://portainer.io) as an optional web UI to administer docker containers.
+- 2018-09-15 [Feature] Add student notes as an optional feature.
+- 2018-09-15 [Feature] Add templates to configurator container, which can now be run separately.
+- 2018-09-15 [Improvement] Rename "up" and "daemon" commands to "run" and "daemonize".
+- 2018-09-15 [Feature] Activate course search and discovery.
+- 2018-09-15 [Bugfix] Deduplicate console logs from lms/cms.
+- 2018-09-05 [Improvement] Use a single email address for all inbound email.
+- 2018-09-04 [Bugfix] Get make commands to work with 'sudo'.
+- 2018-09-02 [Bugfix] Get HTTPS to work for CMS. Thanks @flytreeleft!.
+- 2018-08-28 [Bugfix] Fix certbot image updating.
+- 2018-08-27 [Improvement] Add development requirements to openedx image.
+- 2018-08-27 [Bugfix] Upgrade MongoDB.
+- 2018-08-19 [Improvement] Make Xqueue an optional feature.
+- 2018-08-16 [Feature] Add HTTPS support.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index ad357f5185..671a050b6d 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -1,4 +1,4 @@
Contribution Guidelines
=======================
-Please check the relevant section of the Tutor docs: `https://docs.tutor.overhang.io/tutor.html#contributing `__.
+Please check the relevant section of the Tutor docs: `https://docs.tutor.edly.io/tutor.html#contributing `__.
diff --git a/Dockerfile b/Dockerfile
index 03a7cdd6bd..a3d6d4ba53 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,15 +10,15 @@
# Because this image is still experimental, and we are not quite sure if it's going to
# be very useful, we do not provide any usage documentation.
-FROM docker.io/python:3.7-slim-stretch
+FROM docker.io/python:3.8-slim-stretch
# As per https://github.com/docker/compose/issues/3918
COPY --from=library/docker:19.03 /usr/local/bin/docker /usr/bin/docker
COPY --from=docker/compose:1.24.0 /usr/local/bin/docker-compose /usr/bin/docker-compose
-RUN pip install tutor-openedx
+RUN pip install tutor
RUN mkdir /opt/tutor
-ENV TUTOR_ROOT /opt/tutor
+ENV TUTOR_ROOT=/opt/tutor
EXPOSE 80
EXPOSE 443
diff --git a/MANIFEST.in b/MANIFEST.in
index a4d0269a51..7d53c0c3bd 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,5 @@
include requirements/base.in
+include requirements/plugins.txt
+include requirements/dev.txt
recursive-include tutor/templates *
+include tutor/py.typed
diff --git a/Makefile b/Makefile
index 355924d9d0..b1755a5dc0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,11 @@
.DEFAULT_GOAL := help
.PHONY: docs
-SRC_DIRS = ./tutor ./tests ./bin
+SRC_DIRS = ./tutor ./tests ./bin ./docs
BLACK_OPTS = --exclude templates ${SRC_DIRS}
###### Development
-docs: ## Build html documentation
+docs: ## Build HTML documentation
$(MAKE) -C docs
compile-requirements: ## Compile requirements files
@@ -18,65 +18,79 @@ upgrade-requirements: ## Upgrade requirements files
pip-compile --upgrade requirements/dev.in
pip-compile --upgrade requirements/docs.in
-build-pythonpackage: ## Build a python package ready to upload to pypi
+build-pythonpackage: build-pythonpackage-tutor ## Build Python packages ready to upload to pypi
+
+build-pythonpackage-tutor: ## Build the "tutor" python package for upload to pypi
python setup.py sdist
-push-pythonpackage: ## Push python packages to pypi
- twine upload --skip-existing dist/tutor-*.tar.gz
+push-pythonpackage: ## Push python package to pypi
+ twine upload --skip-existing dist/tutor-$(shell make version).tar.gz
+
+test: test-lint test-unit test-types test-format test-pythonpackage ## Run all tests by decreasing order of priority
-test: test-lint test-unit test-format test-pythonpackage ## Run all tests by decreasing order or priority
+test-static: test-lint test-types test-format ## Run only static tests
test-format: ## Run code formatting tests
black --check --diff $(BLACK_OPTS)
test-lint: ## Run code linting tests
- pylint --errors-only --ignore=templates ${SRC_DIRS}
+ pylint --errors-only --enable=unused-import,unused-argument --ignore=templates --ignore=docs/_ext ${SRC_DIRS}
test-unit: ## Run unit tests
python -m unittest discover tests
+test-types: ## Check type definitions
+ mypy --exclude=templates --ignore-missing-imports --implicit-reexport --strict ${SRC_DIRS}
+
test-pythonpackage: build-pythonpackage ## Test that package can be uploaded to pypi
- twine check dist/tutor-openedx-$(shell make version).tar.gz
+ twine check dist/tutor-$(shell make version).tar.gz
+
+test-k8s: ## Validate the k8s format with kubectl. Not part of the standard test suite.
+ tutor k8s apply --dry-run=client --validate=true
format: ## Format code automatically
black $(BLACK_OPTS)
-bootstrap-dev: ## Install dev requirements
- pip install .
- pip install -r requirements/dev.txt
+isort: ## Sort imports. This target is not mandatory because the output may be incompatible with black formatting. Provided for convenience purposes.
+ isort --skip=templates ${SRC_DIRS}
-bootstrap-dev-plugins: bootstrap-dev ## Install dev requirement and all supported plugins
- pip install -r requirements/plugins.txt
+changelog-entry: ## Create a new changelog entry
+ scriv create
+
+changelog: ## Collect changelog entries in the CHANGELOG.md file
+ scriv collect
+
+###### Code coverage
+
+coverage: ## Run unit-tests before analyzing code coverage and generate report
+ $(MAKE) --keep-going coverage-tests coverage-report
+
+coverage-tests: ## Run unit-tests and analyze code coverage
+ coverage run -m unittest discover
-###### Deployment
+coverage-report: ## Generate CLI report for the code coverage
+ coverage report
+
+coverage-html: coverage-report ## Generate HTML report for the code coverage
+ coverage html
+
+coverage-browse-report: coverage-html ## Open the HTML report in the browser
+ sensible-browser htmlcov/index.html
+
+###### Continuous integration tasks
bundle: ## Bundle the tutor package in a single "dist/tutor" executable
pyinstaller tutor.spec
-dist/tutor:
- $(MAKE) bundle
-
-nightly: ## Create a "nightly" release
- $(MAKE) tag TAG=nightly
-
-release: test ## Create a release tag and push it to origin
- $(MAKE) retag release-origin release-overhangio TAG=v$(shell make version)
-
-retag:
- @echo "=== Creating tag $(TAG)"
- git tag -d $(TAG) || true
- git tag $(TAG)
-release-origin:
- @echo "=== Pushing tag $(TAG) to origin"
- git push origin
- git push origin :$(TAG) || true
- git push origin $(TAG)
-release-overhangio:
- @echo "=== Pushing tag $(TAG) to overhangio"
- git push overhangio
- git push overhangio :$(TAG) || true
- git push overhangio $(TAG)
-###### Continuous integration tasks
+bootstrap-dev: ## Install dev requirements
+ pip install .
+ pip install -r requirements/dev.txt
+
+bootstrap-dev-plugins: bootstrap-dev ## Install dev requirements and all supported plugins
+ pip install -r requirements/plugins.txt
+
+pull-base-images: # Manually pull base images
+ docker image pull docker.io/ubuntu:20.04
ci-info: ## Print info about environment
python --version
@@ -89,35 +103,10 @@ ci-test-bundle: ## Run basic tests on bundle
yes "" | ./dist/tutor config save --interactive
./dist/tutor config save
./dist/tutor plugins list
- # ./dist/tutor plugins enable discovery ecommerce figures license minio notes xqueue
- ./dist/tutor plugins enable discovery ecommerce license minio notes xqueue
+ ./dist/tutor plugins enable android discovery ecommerce forum license mfe minio notes webui xqueue
./dist/tutor plugins list
./dist/tutor license --help
-./releases/github-release: ## Download github-release binary
- mkdir -p releases/
- cd releases/ \
- && curl -sSL -o ./github-release.bz2 "https://github.com/meterup/github-release/releases/download/v0.7.5/$(shell uname -s | tr "[:upper:]" "[:lower:]")-amd64-github-release.bz2" \
- && bzip2 -d -f ./github-release.bz2 \
- && chmod a+x ./github-release
-
-ci-push-bundle: ./releases/github-release ## Upload assets to github
- sed "s/TUTOR_VERSION/v$(shell make version)/g" docs/_release_description.md > releases/description.md
- git log -1 --pretty=format:%b >> releases/description.md
- ./releases/github-release release \
- --user overhangio \
- --repo tutor \
- --tag "v$(shell make version)" \
- --name "v$(shell make version)" \
- --description "$$(cat releases/description.md)" || true
- ./releases/github-release upload \
- --user overhangio \
- --repo tutor \
- --tag "v$(shell make version)" \
- --name "tutor-$$(uname -s)_$$(uname -m)" \
- --file ./dist/tutor \
- --replace
-
ci-bootstrap-images:
pip install .
tutor config save
@@ -125,10 +114,10 @@ ci-bootstrap-images:
###### Additional commands
version: ## Print the current tutor version
- @python -c 'import io, os; about = {}; exec(io.open(os.path.join("tutor", "__about__.py"), "rt", encoding="utf-8").read(), about); print(about["__version__"])'
+ @python -c 'import io, os; about = {}; exec(io.open(os.path.join("tutor", "__about__.py"), "rt", encoding="utf-8").read(), about); print(about["__package_version__"])'
ESCAPE =
help: ## Print this help
@grep -E '^([a-zA-Z_-]+:.*?## .*|######* .+)$$' Makefile \
- | sed 's/######* \(.*\)/\n $(ESCAPE)[1;31m\1$(ESCAPE)[0m/g' \
+ | sed 's/######* \(.*\)/@ $(ESCAPE)[1;31m\1$(ESCAPE)[0m/g' | tr '@' '\n' \
| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[33m%-30s\033[0m %s\n", $$1, $$2}'
diff --git a/README.rst b/README.rst
index 5b64a1e079..fc0d3b2504 100644
--- a/README.rst
+++ b/README.rst
@@ -1,10 +1,6 @@
-.. _readme_intro_start:
-
-Tutor: the docker-based Open edX distribution designed for peace of mind
+Tutor: the Docker-based Open edX distribution designed for peace of mind
========================================================================
-|
-
.. image:: https://overhang.io/static/img/tutor-logo.svg
:alt: Tutor logo
:width: 500px
@@ -12,66 +8,76 @@ Tutor: the docker-based Open edX distribution designed for peace of mind
|
-.. image:: https://img.shields.io/travis/overhangio/tutor.svg?label=Release%20build&style=flat-square
- :alt: Release build status
- :target: https://travis-ci.org/overhangio/tutor
+.. _readme_intro_start:
+
+.. image:: https://img.shields.io/static/v1?logo=github&label=Git&style=flat-square&color=brightgreen&message=Source%20code
+ :alt: Source code
+ :target: https://github.com/overhangio/tutor
-.. image:: https://img.shields.io/badge/docs-current-blue.svg?style=flat-square
- :alt: Documentation
- :target: https://docs.tutor.overhang.io
+.. image:: https://img.shields.io/static/v1?logo=discourse&label=Forums&style=flat-square&color=ff0080&message=discuss.openedx.org
+ :alt: Forums
+ :target: https://discuss.openedx.org/tag/tutor
-.. image:: https://img.shields.io/github/issues/overhangio/tutor.svg?style=flat-square
- :alt: GitHub issues
- :target: https://github.com/overhangio/tutor/issues
+.. image:: https://img.shields.io/static/v1?logo=readthedocs&label=Documentation&style=flat-square&color=blue&message=docs.tutor.edly.io
+ :alt: Documentation
+ :target: https://docs.tutor.edly.io
-.. image:: https://img.shields.io/github/issues-closed/overhangio/tutor.svg?colorB=brightgreen&style=flat-square
- :alt: GitHub closed issues
- :target: https://github.com/overhangio/tutor/issues?q=is%3Aclosed
+.. image:: https://img.shields.io/pypi/v/tutor?logo=python&logoColor=white
+ :alt: PyPI releases
+ :target: https://pypi.org/project/tutor
.. image:: https://img.shields.io/github/license/overhangio/tutor.svg?style=flat-square
- :alt: AGPL License
- :target: https://www.gnu.org/licenses/agpl-3.0.en.html
+ :alt: AGPL License
+ :target: https://www.gnu.org/licenses/agpl-3.0.en.html
-**Tutor** is a docker-based `Open edX `_ distribution, both for production and local development. The goal of Tutor is to make it easy to deploy, customize, upgrade and scale Open edX. Tutor is reliable, fast, extensible, and it is already used by dozens of Open edX platforms around the world.
+.. image:: https://img.shields.io/static/v1?logo=youtube&label=YouTube&style=flat-square&color=ff0000&message=@tutor-edly
+ :alt: Follow us on Youtube
+ :target: https://www.youtube.com/@tutor-edly
-Do you need professional assistance setting up or managing your Open edX platform? Overhang.IO provides online support as part of its `Long Term Support (LTS) offering `__.
+**Tutor** is the official Docker-based `Open edX `_ distribution, both for production and local development. The goal of Tutor is to make it easy to deploy, customise, upgrade and scale Open edX. Tutor is reliable, fast, extensible, and it is already used to deploy hundreds of Open edX platforms around the world.
+
+Do you need professional assistance setting up or managing your Open edX platform? `Edly `__ provides online support as part of its `Open edX installation service `__.
Features
--------
* 100% `open source `__
* Runs entirely on Docker
-* World-famous 1-click `installation and upgrades `__
-* Comes with batteries included: `theming `__, `SCORM `__, `HTTPS `__, `web-based administration interface `__, `mobile app `__, `custom translations `__...
-* Extensible architecture with `plugins `__
-* Works with `Kubernetes `__
-* No technical skill required with the `1-click Tutor AWS image `__
-* Amazing plugins available with `Tutor Wizard Edition `__
+* World-famous 1-click `installation and upgrades `__
+* Comes with batteries included: `theming `__, `SCORM `__, `HTTPS `__, `web-based administration interface `__, `mobile app `__, `custom translations `__...
+* Extensible architecture with `plugins `__
+* Works with `Kubernetes `__
+* No technical skill required with the `zero-click Tutor AWS image `__
.. _readme_intro_end:
-.. image:: ./docs/img/quickstart.gif
- :alt: Tutor local quickstart
- :target: https://terminalizer.com/view/91b0bfdd557
+.. image:: ./docs/img/launch.webp
+ :alt: Tutor local launch
+ :target: https://www.terminalizer.com/view/3a8d55835686
Quickstart
----------
1. Install the `latest stable release `_ of Tutor
-2. Run ``tutor local quickstart``
+2. Run ``tutor local launch``
3. You're done!
Documentation
-------------
-Extensive documentation is available online: https://docs.tutor.overhang.io/
+Extensive documentation is available: https://docs.tutor.edly.io/
+
+Is there a problem?
+-------------------
+
+Please follow the instructions from the `troubleshooting section `__ in the docs.
.. _readme_support_start:
Support
-------
-To get community support, go to the official discussion forums: https://discuss.overhang.io. For official support, please subscribe to a Long Term Support (LTS) license at https://overhang.io/tutor/pricing.
+To get community support, go to the official Open edX discussion forum: https://discuss.openedx.org. For official support, `Edly `__ provides professional assistance as part of its `Open edX installation service `__.
.. _readme_support_end:
@@ -80,6 +86,11 @@ To get community support, go to the official discussion forums: https://discuss.
Contributing
------------
-We welcome contributions to Tutor! To learn how you can contribute, please check the relevant section of the Tutor docs: `https://docs.tutor.overhang.io/tutor.html#contributing `__.
+We welcome contributions to Tutor! To learn how you can contribute, please check the relevant section of the Tutor docs: `https://docs.tutor.edly.io/tutor.html#contributing `__.
+
+.. _readme_contributing_end:
+
+License
+-------
-.. _readme_contributing_end:
\ No newline at end of file
+This work is licensed under the terms of the `GNU Affero General Public License (AGPL) `_.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000000..38079484f8
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,19 @@
+# Tutor Ethical Vulnerability Disclosure Policy
+
+
+## Reporting a Vulnerability
+
+To ensure the health of the codebase and the larger Open edX and Tutor communities, please do not create GitHub issues for a security vulnerability. Report any security vulnerabilities or concerns by sending an email to [security.tutor@edly.io](mailto:security.tutor@edly.io). To ensure a timely triage and fix of the security issue, include as many details you can when reporting the vulnerability. Some pieces of information to consider:
+
+* The nature of the vulnerability, e.g.
+ * Authentication and Authorization
+ * Data Integrity and Confidentiality
+ * Security Configurations
+ * Third-party dependencies
+* The impact of the security risk
+* A detailed description of the steps necessary to reproduce the issue
+* The links to the vulnerable code
+* The links to third-party libraries/packages if the vulnerability is present in such a dependency.
+
+## Bug Bounty
+Edly/Tutor does not offer a bug bounty for reported vulnerabilities.
diff --git a/bin/main.py b/bin/main.py
index feaf04c2c7..d5e570f7e6 100755
--- a/bin/main.py
+++ b/bin/main.py
@@ -1,21 +1,17 @@
#!/usr/bin/env python3
-from tutor.plugins import OfficialPlugin
+from tutor import hooks
+from tutor.commands.cli import main
+from tutor.plugins.v0 import OfficialPlugin
-# Manually install plugins (this is for creating the bundle)
-for plugin_name in [
- "discovery",
- "ecommerce",
- # "figures",
- "license",
- "minio",
- "notes",
- "xqueue",
-]:
- try:
- OfficialPlugin.load(plugin_name)
- except ImportError:
- pass
-from tutor.commands.cli import main
+@hooks.Actions.CORE_READY.add()
+def _discover_official_plugins() -> None:
+ # Manually discover plugins: that's because entrypoint plugins are not properly
+ # detected within the binary bundle.
+ with hooks.Contexts.PLUGINS.enter():
+ OfficialPlugin.discover_all()
+
-main()
+if __name__ == "__main__":
+ # Call the regular main function, which will not detect any entrypoint plugin
+ main()
diff --git a/changelog.d/20240726_202449_danyal.faheem_mysql_upgrade_5_7_to_8_4.md b/changelog.d/20240726_202449_danyal.faheem_mysql_upgrade_5_7_to_8_4.md
new file mode 100644
index 0000000000..01275c273d
--- /dev/null
+++ b/changelog.d/20240726_202449_danyal.faheem_mysql_upgrade_5_7_to_8_4.md
@@ -0,0 +1,2 @@
+- [Bugfix] Do not directly upgrade MySQL from v5.7 to v8.4 when upgrading from quince as MySQL does not allow that. First, upgrade to v8.1 and then to v8.4. (by @Danyal-Faheem)
+ This process should be automatic for most users. However, if you are running a third-party MySQL (i.e., RUN_MYSQL=false), you are expected to perform this process yourself. Please refer to the third-party provider's documentation for detailed instructions. Ensuring that your MySQL version is up-to-date is crucial for maintaining compatibility and security.
\ No newline at end of file
diff --git a/changelog.d/20241018_122745_danyal.faheem_run_mysql_8_1_as_separate_container.md b/changelog.d/20241018_122745_danyal.faheem_run_mysql_8_1_as_separate_container.md
new file mode 100644
index 0000000000..a4b5403c75
--- /dev/null
+++ b/changelog.d/20241018_122745_danyal.faheem_run_mysql_8_1_as_separate_container.md
@@ -0,0 +1 @@
+- [Bugfix] Run MySQL 8.1 as a separate container during upgrade from Olive to Redwood as it crashed otherwise due to the `--mysql-native-password` option not being present. (by @Danyal-Faheem)
\ No newline at end of file
diff --git a/changelog.d/20241031_144431_regis_no_delete_env.md b/changelog.d/20241031_144431_regis_no_delete_env.md
new file mode 100644
index 0000000000..e84aac0782
--- /dev/null
+++ b/changelog.d/20241031_144431_regis_no_delete_env.md
@@ -0,0 +1 @@
+- [Improvement] Do not prompt for environment deletion by default on `tutor config save --interactive`. (by @regisb)
diff --git a/changelog.d/20241111_163102_dawoud.sheraz_remove_py38_references.md b/changelog.d/20241111_163102_dawoud.sheraz_remove_py38_references.md
new file mode 100644
index 0000000000..aeead7e20c
--- /dev/null
+++ b/changelog.d/20241111_163102_dawoud.sheraz_remove_py38_references.md
@@ -0,0 +1 @@
+- π₯ [Deprecation] Drop support for python 3.8 and set Python 3.9 as the minimum supported python version. (by @DawoudSheraz)
diff --git a/changelog.d/20241119_100430_crisgarta8_celery_queues.md b/changelog.d/20241119_100430_crisgarta8_celery_queues.md
new file mode 100644
index 0000000000..d0ec11de84
--- /dev/null
+++ b/changelog.d/20241119_100430_crisgarta8_celery_queues.md
@@ -0,0 +1 @@
+- π₯ [Feature] Add a filter to define the celery workers startup command. (by @Ian2012)
diff --git a/changelog.d/20241119_111602_fghaas_image_manifest.md b/changelog.d/20241119_111602_fghaas_image_manifest.md
new file mode 100644
index 0000000000..28e6cc901c
--- /dev/null
+++ b/changelog.d/20241119_111602_fghaas_image_manifest.md
@@ -0,0 +1,8 @@
+- [Improvement] When building images with
+ `tutorΒ imagesΒ buildΒ --cache-to-registry`, use an OCI-compliant cache
+ artifact format that should be universally compatible with all
+ registries. This enables the use of that option when working with
+ third-party registries such as [Harbor](https://goharbor.io/) or
+ [ECR](https://aws.amazon.com/ecr/). Requires
+ [BuildKitΒ 0.12](https://github.com/moby/buildkit/releases/tag/v0.12.0)
+ or later. (by @angonz and @fghaas)
diff --git a/changelog.d/scriv.ini b/changelog.d/scriv.ini
new file mode 100644
index 0000000000..6333f3ac5c
--- /dev/null
+++ b/changelog.d/scriv.ini
@@ -0,0 +1,8 @@
+[scriv]
+version = literal: tutor/__about__.py: __version__
+categories =
+format = md
+md_header_level = 2
+new_fragment_template = file: changelog.d/scriv/new_fragment.${config:format}.j2
+entry_title_template = file: changelog.d/scriv/entry_title.${config:format}.j2
+ghrel_template = file: changelog.d/scriv/github_release.${config:format}.j2
diff --git a/changelog.d/scriv/entry_title.md.j2 b/changelog.d/scriv/entry_title.md.j2
new file mode 100644
index 0000000000..7afe89477c
--- /dev/null
+++ b/changelog.d/scriv/entry_title.md.j2
@@ -0,0 +1 @@
+{% if version %}v{{ version }} {% endif %}({{ date.strftime('%Y-%m-%d') }})
diff --git a/changelog.d/scriv/github_release.md.j2 b/changelog.d/scriv/github_release.md.j2
new file mode 100644
index 0000000000..8d78d8ca2a
--- /dev/null
+++ b/changelog.d/scriv/github_release.md.j2
@@ -0,0 +1,14 @@
+Install this version from pip with:
+
+ pip install "tutor[full]=={{ version.vtext[1:] }}"
+
+Or download the compiled binaries:
+
+ sudo curl -L "https://github.com/overhangio/tutor/releases/download/{{ version }}/tutor-$(uname -s)_$(uname -m)" -o /usr/local/bin/tutor
+ sudo chmod 0755 /usr/local/bin/tutor
+
+See the [installation docs](https://docs.tutor.edly.io/install.html) for more installation options and instructions.
+
+## Changes
+
+{{ body }}
diff --git a/changelog.d/scriv/new_fragment.md.j2 b/changelog.d/scriv/new_fragment.md.j2
new file mode 100644
index 0000000000..78988a42c7
--- /dev/null
+++ b/changelog.d/scriv/new_fragment.md.j2
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/docs/Makefile b/docs/Makefile
index 8b29286b31..8c3882be42 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,11 +1,17 @@
.DEFAULT_GOAL := html
.PHONY: help
+build:
+ sphinx-build -b html -a -E -n $(BUILD_ARGS) "." "_build/html"
+
html:
- sphinx-build -b html -a -E "." "_build/html"
+ $(MAKE) build BUILD_ARGS="-W --keep-going"
browse:
sensible-browser _build/html/index.html
-watch: html browse
- while true; do inotifywait -e modify *.rst */*.rst ../*.rst conf.py; $(MAKE) html; done
+watch: build browse
+ while true; do $(MAKE) wait-for-change build || true; done
+
+wait-for-change:
+ inotifywait -e modify $(shell find . -name "*.rst") ../*.rst ../tutor/hooks/*.py conf.py
diff --git a/docs/__init__.py b/docs/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/_ext/tutordocs.py b/docs/_ext/tutordocs.py
new file mode 100644
index 0000000000..eb8758770b
--- /dev/null
+++ b/docs/_ext/tutordocs.py
@@ -0,0 +1,15 @@
+"""
+This module is heavily inspired by Django's djangodocs.py:
+https://github.com/django/django/blob/main/docs/_ext/djangodocs.py
+"""
+
+from sphinx.application import Sphinx
+
+
+def setup(app: Sphinx) -> None:
+ # https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_crossref_type
+ app.add_crossref_type(
+ directivename="patch",
+ rolename="patch",
+ indextemplate="pair: %s; patch",
+ )
diff --git a/docs/_release_description.md b/docs/_release_description.md
deleted file mode 100644
index 0e34d97c6f..0000000000
--- a/docs/_release_description.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Tutor can be installed simply by downloading the compiled binaries:
-
- sudo curl -L "https://github.com/overhangio/tutor/releases/download/TUTOR_VERSION/tutor-$(uname -s)_$(uname -m)" -o /usr/local/bin/tutor
- sudo chmod 0755 /usr/local/bin/tutor
-
-See the [installation docs](https://docs.tutor.overhang.io/install.html) for more installation options and instructions.
-
-## Changes
diff --git a/docs/conf.py b/docs/conf.py
index a29183d896..f73d34cd6f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,5 +1,9 @@
+from __future__ import annotations
+
import io
import os
+import sys
+from typing import Any, Dict, List
import docutils
import docutils.parsers.rst
@@ -7,8 +11,8 @@
# -- Project information -----------------------------------------------------
project = "Tutor"
-copyright = ""
-author = "Overhang.io"
+copyright = "" # pylint: disable=redefined-builtin
+author = "Overhang.IO"
# The short X.Y version
version = ""
@@ -21,10 +25,60 @@
templates_path = ["_templates"]
source_suffix = ".rst"
master_doc = "index"
-language = None
+language = "en"
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
pygments_style = None
+# Autodocumentation of modules
+extensions.append("sphinx.ext.autodoc")
+autodoc_typehints = "description"
+# For the life of me I can't get the docs to compile in nitpicky mode without these
+# ignore statements. You are most welcome to try and remove them.
+# To make matters worse, some ignores are only required for some versions of Python,
+# from 3.8 to 3.10...
+nitpick_ignore = [
+ # Sphinx does not handle ParamSpec arguments
+ ("py:class", "T.args"),
+ ("py:class", "T.kwargs"),
+ ("py:class", "T2.args"),
+ ("py:class", "T2.kwargs"),
+ # Sphinx doesn't know about the following classes
+ ("py:class", "click.Command"),
+ ("py:class", "t.Any"),
+ ("py:class", "t.Callable"),
+ ("py:class", "t.Iterator"),
+ ("py:class", "t.Optional"),
+ # python 3.10
+ ("py:class", "NoneType"),
+ ("py:class", "click.core.Command"),
+ # Python 3.12
+ ("py:class", "FilterCallbackFunc"),
+]
+# Resolve type aliases here
+# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_type_aliases
+autodoc_type_aliases: dict[str, str] = {
+ # python 3.10
+ "T": "tutor.core.hooks.actions.T",
+ "T2": "tutor.core.hooks.filters.T2",
+ # # python 3.12
+ "L": "tutor.core.hooks.filters.L",
+ "FilterCallbackFunc": "tutor.core.hooks.filters.FilterCallbackFunc",
+ # https://stackoverflow.com/questions/73223417/type-aliases-in-type-hints-are-not-preserved
+ # https://github.com/sphinx-doc/sphinx/issues/10455
+ # https://github.com/sphinx-doc/sphinx/issues/10785
+ # https://github.com/emdgroup/baybe/pull/67
+ "Action": "tutor.core.hooks.actions.Action",
+ "Filter": "tutor.core.hooks.filters.Filter",
+}
+
+
+# -- Sphinx-Click configuration
+# https://sphinx-click.readthedocs.io/
+extensions.append("sphinx_click")
+# This is to avoid the addition of the local username to the docs
+os.environ["HOME"] = "~"
+# Make sure that sphinx-click can find the tutor module
+sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
# -- Options for HTML output -------------------------------------------------
html_theme = "sphinx_rtd_theme"
@@ -42,7 +96,7 @@
html_static_path = ["img"]
# Custom settings
-html_logo = "./img/tutor-logo.png"
+html_logo = "https://overhang.io/static/img/tutor-logo.svg"
html_favicon = "./img/favicon.png"
html_show_sourcelink = False
html_display_github = True
@@ -55,49 +109,51 @@
# Custom variables
here = os.path.abspath(os.path.dirname(__file__))
-about = {}
+about: Dict[str, str] = {}
with io.open(
os.path.join(here, "..", "tutor", "__about__.py"), "rt", encoding="utf-8"
) as f:
+ # pylint: disable=exec-used
exec(f.read(), about)
-rst_prolog = """
-.. |tutor_version| replace:: {}
-""".format(
- about["__version__"],
-)
+rst_prolog = f"""
+.. |tutor_version| replace:: {about["__version__"]}
+"""
# Custom directives
def youtube(
- _name,
- _args,
- _options,
- content,
- _lineno,
- _contentOffset,
- _blockText,
- _state,
- _stateMachine,
-):
- """ Restructured text extension for inserting youtube embedded videos """
+ _name: Any,
+ _args: Any,
+ _options: Any,
+ content: List[str],
+ _lineno: Any,
+ _contentOffset: Any,
+ _blockText: Any,
+ _state: Any,
+ _stateMachine: Any,
+) -> Any:
+ """Restructured text extension for inserting youtube embedded videos"""
if not content:
return []
video_id = content[0]
return [
docutils.nodes.raw(
"",
- """
+ f"""
""".format(
- video_id=video_id
- ),
+""",
format="html",
)
]
-youtube.content = True
-docutils.parsers.rst.directives.register_directive("youtube", youtube)
+# Tutor's own extension
+sys.path.append(os.path.join(os.path.dirname(__file__), "_ext"))
+extensions.append("tutordocs")
+
+
+setattr(youtube, "content", True)
+docutils.parsers.rst.directives.register_directive("youtube", youtube) # type: ignore
diff --git a/docs/configuration.rst b/docs/configuration.rst
index d61d9494b0..6e40797a14 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -3,19 +3,19 @@
Configuration and customisation
===============================
-Tutor offers plenty of possibilities for platform customisation out of the box. There are two main ways in which the base Open edX installation can be customized:
+Tutor offers plenty of possibilities for platform customisation out of the box. There are two main ways in which the base Open edX installation can be customised:
a. Modifying the Tutor :ref:`configuration parameters `.
b. Modifying the :ref:`Open edX docker image ` that runs the Open edX platform.
-This section does not cover :ref:`plugin development `. For simple changes, such as modifying the ``*.env.json`` files or the edx-platform settings, *you should not fork edx-platform or tutor*! Instead, you should create a simple :ref:`plugin for Tutor `.
+This section does not cover :ref:`plugin development `. For simple changes, such as modifying the ``*.env.yml`` files or the edx-platform settings, *you should not fork edx-platform or tutor*! Instead, you should create a simple :ref:`plugin for Tutor `.
.. _configuration:
Configuration
-------------
-With Tutor, all Open edX deployment parameters are stored in a single ``config.yml`` file. This is the file that is generated when you run ``tutor local quickstart`` or ``tutor config save``. To view the content of this file, run::
+With Tutor, all Open edX deployment parameters are stored in a single ``config.yml`` file. This is the file that is generated when you run ``tutor local launch`` or ``tutor config save``. To view the content of this file, run::
cat "$(tutor config printroot)/config.yml"
@@ -31,7 +31,7 @@ Or from the system environment::
export TUTOR_PARAM1=VALUE1
-Once the base configuration is created or updated, the environment is automatically re-generated. The environment is the set of all files required to manage an Open edX platform: Dockerfile, ``lms.env.json``, settings files, etc. You can view the environment files in the ``env`` folder::
+Once the base configuration is created or updated, the environment is automatically re-generated. The environment is the set of all files required to manage an Open edX platform: Dockerfile, ``lms.env.yml``, settings files, etc. You can view the environment files in the ``env`` folder::
ls "$(tutor config printroot)/env"
@@ -40,9 +40,6 @@ With an up-to-date environment, Tutor is ready to launch an Open edX platform an
Individual service activation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ``RUN_LMS`` (default: ``true``)
-- ``RUN_CMS`` (default: ``true``)
-- ``RUN_FORUM`` (default: ``true``)
- ``RUN_ELASTICSEARCH`` (default: ``true``)
- ``RUN_MONGODB`` (default: ``true``)
- ``RUN_MYSQL`` (default: ``true``)
@@ -61,10 +58,48 @@ Custom images
*************
- ``DOCKER_IMAGE_OPENEDX`` (default: ``"{{ DOCKER_REGISTRY }}overhangio/openedx:{{ TUTOR_VERSION }}"``)
-- ``DOCKER_IMAGE_ANDROID`` (default: ``"{{ DOCKER_REGISTRY }}overhangio/openedx-android:{{ TUTOR_VERSION }}"``)
-- ``DOCKER_IMAGE_FORUM`` (default: ``"{{ DOCKER_REGISTRY }}overhangio/openedx-forum:{{ TUTOR_VERSION }}"``)
-These configuration parameters define which image to run for each service. By default, the docker image tag matches the Tutor version it was built with.
+This configuration parameter defines the name of the Docker image to run for the lms and cms containers. By default, the Docker image tag matches the Tutor version it was built with.
+
+- ``DOCKER_IMAGE_OPENEDX_DEV`` (default: ``"openedx-dev:{{ TUTOR_VERSION }}"``)
+
+This configuration parameter defines the name of the Docker image to run the development version of the lms and cms containers. By default, the Docker image tag matches the Tutor version it was built with.
+
+.. https://hub.docker.com/r/devture/exim-relay/tags
+
+- ``DOCKER_IMAGE_CADDY`` (default: ``"docker.io/caddy:2.6.2"``)
+
+This configuration parameter defines which Caddy Docker image to use.
+
+- ``DOCKER_IMAGE_ELASTICSEARCH`` (default: ``"docker.io/elasticsearch:7.17.9"``)
+
+This configuration parameter defines which Elasticsearch Docker image to use.
+
+- ``DOCKER_IMAGE_MONGODB`` (default: ``"docker.io/mongo:7.0.7"``)
+
+This configuration parameter defines which MongoDB Docker image to use.
+
+.. https://hub.docker.com/_/mysql/tags?page=1&name=8.0
+
+- ``DOCKER_IMAGE_MYSQL`` (default: ``"docker.io/mysql:8.4.0"``)
+
+This configuration parameter defines which MySQL Docker image to use.
+
+.. https://hub.docker.com/_/redis/tags
+
+- ``DOCKER_IMAGE_REDIS`` (default: ``"docker.io/redis:7.2.4"``)
+
+This configuration parameter defines which Redis Docker image to use.
+
+.. https://hub.docker.com/r/devture/exim-relay/tags
+
+- ``DOCKER_IMAGE_SMTP`` (default: ``"docker.io/devture/exim-relay:4.96-r1-0``)
+
+This configuration parameter defines which Simple Mail Transfer Protocol (SMTP) Docker image to use.
+
+- ``DOCKER_IMAGE_PERMISSIONS`` (default: ``"{{ DOCKER_REGISTRY }}overhangio/openedx-permissions:{{ TUTOR_VERSION }}"``)
+
+This configuration parameter defines the Docker image to be used for setting file permissions. The default image sets all containers to be run as unprivileged users.
Custom registry
***************
@@ -77,35 +112,102 @@ You may want to pull/push images from/to a custom docker registry. For instance,
(the trailing ``/`` is important)
+.. _openedx_configuration:
+
+Compose
+*******
+
+- ``DEV_PROJECT_NAME`` (default: ``"{{ TUTOR_APP }}_dev"``)
+
+This configuration parameter sets the Development version of the Docker Compose project name.
+
+- ``LOCAL_PROJECT_NAME`` (default: ``"{{ TUTOR_APP }}_local"``)
+
+This configuration parameter sets the Local version of the Docker Compose project name.
+
Open edX customisation
~~~~~~~~~~~~~~~~~~~~~~
-- ``OPENEDX_COMMON_VERSION`` (default: ``"open-release/koa.1"``)
+- ``EDX_PLATFORM_REPOSITORY`` (default: ``"https://github.com/openedx/edx-platform.git"``)
+
+This defines the git repository from which you install Open edX platform code. If you run an Open edX fork with custom patches, set this to your own git repository. You may also override this configuration parameter at build time, by providing a ``--build-arg`` option.
+
+- ``OPENEDX_COMMON_VERSION`` (default: ``"open-release/redwood.3"``, or ``master`` in :ref:`nightly `)
This defines the default version that will be pulled from all Open edX git repositories.
+- ``EDX_PLATFORM_VERSION`` (default: the value of ``OPENEDX_COMMON_VERSION``)
+
+This defines the version that will be pulled from just the Open edX platform git repositories. You may also override this configuration parameter at build time, by providing a ``--build-arg`` option.
+
- ``OPENEDX_CMS_UWSGI_WORKERS`` (default: ``2``)
- ``OPENEDX_LMS_UWSGI_WORKERS`` (default: ``2``)
-By default there are 2 `uwsgi worker processes `__ to serve requests for the LMS and the CMS. However, each workers requires upwards of 500 Mb of RAM. You should reduce this value to 1 if your computer/server does not have enough memory.
+By default, there are 2 `uwsgi worker processes `__ to serve requests for the LMS and the CMS. However, each worker requires upwards of 500 Mb of RAM. You should reduce this value to 1 if your computer/server does not have enough memory.
+- ``OPENEDX_CELERY_REDIS_DB`` (default: ``0``)
+- ``OPENEDX_CACHE_REDIS_DB`` (default: ``1``)
-Vendor services
-~~~~~~~~~~~~~~~
+These two configuration parameters define which Redis database to use for Open edX cache and celery task.
-Caddy
-*****
+.. _openedx_extra_pip_requirements:
+
+- ``OPENEDX_EXTRA_PIP_REQUIREMENTS`` (default: ``[]``)
+
+Define extra pip packages that are going to be installed for edx-platform.
+
+- ``NPM_REGISTRY`` (default: ``"https://registry.npmjs.org/"``)
+
+This defines the registry from which you'll be pulling NPM packages when building Docker images. Like ``EDX_PLATFORM_REPOSITORY``, this can be overridden at build time with a ``--build-arg`` option.
+
+- ``OPENEDX_AWS_ACCESS_KEY`` (default: ``""``)
+
+This configuration parameter sets the Django setting ``AWS_ACCESS_KEY_ID`` in edx-platform's LMS, CMS, envs, and production.py for use by the library django-storages with Amazon S3.
+
+- ``OPENEDX_AWS_SECRET_ACCESS_KEY`` (default: ``""``)
+
+This configuration parameter sets the Django setting ``AWS_SECRET_ACCESS_KEY`` in edx-platform's LMS, CMS, envs, and production.py for use by the library django-storages with Amazon S3.
+
+- ``OPENEDX_MYSQL_DATABASE`` (default: ``"openedx"``)
+
+This configuration parameter sets the name of the MySQL Database to be used by the Open edX Instance.
+
+- ``OPENEDX_MYSQL_USERNAME`` (default: ``"openedx"``)
+
+This configuration parameter sets the username associated with the MySQL Database.
+
+CMS OAUTH2 SSO
+~~~~~~~~~~~~~~
+
+- ``CMS_OAUTH2_KEY_SSO`` (default: ``"cms-sso"``)
+
+This defines the Studio's (CMS) OAUTH 2.0 Login (Key or Client ID) for SSO in the production environment.
+
+- ``CMS_OAUTH2_KEY_SSO_DEV`` (default: ``"cms-sso-dev"``)
+
+This defines the Studio's (CMS) OAUTH 2.0 Login (Key or Client ID) for SSO in the development environment.
+
+For more information, see `Enabling OAuth for Studio login `__.
-- ``RUN_CADDY`` (default: ``true``)
+JWTs
+~~~~
-`Caddy `__ is a web server used in Tutor as a web proxy for the generation of SSL/TLS certificates at runtime. If ``RUN_CADDY`` is set to ``false`` then we assume that SSL termination does not occur in the Caddy container, and thus the ``caddy`` container is not started.
+- ``JWT_COMMON_AUDIENCE`` (default: ``"openedx"``)
+- ``JWT_COMMON_ISSUER`` (default: ``"{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}/oauth2"``)
+- ``JWT_COMMON_SECRET_KEY`` (default: ``"{{ OPENEDX_SECRET_KEY }}"``)
-Nginx
+These configuration parameters are rendered into the ``JWT_AUTH`` dictionary with keys ``JWT_AUDIENCE``, ``JWT_ISSUER``, and ``JWT_SECRET_KEY``, respectively. These parameters may be changed in order to create a custom user login for testing purposes.
+
+Vendor services
+~~~~~~~~~~~~~~~
+
+Caddy
*****
-- ``NGINX_HTTP_PORT`` (default: ``80``)
+- ``CADDY_HTTP_PORT`` (default: ``80``)
+- ``ENABLE_WEB_PROXY`` (default: ``true``)
-Nginx is used to route web traffic to the various applications and to serve static assets. When ``RUN_CADDY`` is false, the ``NGINX_HTTP_PORT`` is exposed on the host.
+`Caddy `__ is a web server used in Tutor both as a web proxy and for the generation of SSL/TLS certificates at runtime. Port indicated by ``CADDY_HTTP_PORT`` is exposed on the host, in addition to port 443. If ``ENABLE_WEB_PROXY`` is set to ``false`` then we assume that SSL termination does not occur in the Caddy container and only ``CADDY_HTTP_PORT`` is exposed on the host.
MySQL
*****
@@ -116,13 +218,16 @@ MySQL
- ``MYSQL_ROOT_USERNAME`` (default: ``"root"``)
- ``MYSQL_ROOT_PASSWORD`` (default: randomly generated) Note that you are responsible for creating the root user if you are using a managed database.
-By default, a running Open edX platform deployed with Tutor includes all necessary 3rd-party services, such as MySQL, MongoDb, etc. But it's also possible to store data on a separate database, such as `Amazon RDS `_. For instance, to store data on an external MySQL database, set the following configuration::
+By default, a running Open edX platform deployed with Tutor includes all necessary 3rd-party services, such as MySQL, MongoDb, etc. But it's also possible to store data on a separate database, such as `Amazon RDS `_. For instance, to store data on an external MySQL database set the following configuration::
RUN_MYSQL: false
MYSQL_HOST: yourhost
MYSQL_ROOT_USERNAME:
MYSQL_ROOT_PASSWORD:
+.. note::
+ When configuring an external MySQL database, please make sure it is using version 8.4.
+
Elasticsearch
*************
@@ -131,22 +236,28 @@ Elasticsearch
- ``ELASTICSEARCH_PORT`` (default: ``9200``)
- ``ELASTICSEARCH_HEAP_SIZE`` (default: ``"1g"``)
-Mongodb
+MongoDB
*******
- ``RUN_MONGODB`` (default: ``true``)
-- ``MONGODB_HOST`` (default: ``"mongodb"``)
- ``MONGODB_DATABASE`` (default: ``"openedx"``)
+- ``MONGODB_HOST`` (default: ``"mongodb"``)
+- ``MONGODB_PASSWORD`` (default: ``""``)
- ``MONGODB_PORT`` (default: ``27017``)
- ``MONGODB_USERNAME`` (default: ``""``)
-- ``MONGODB_PASSWORD`` (default: ``""``)
+- ``MONGODB_USE_SSL`` (default: ``false``)
+- ``MONGODB_REPLICA_SET`` (default: ``""``)
+- ``MONGODB_AUTH_MECHANISM`` (default: ``""``)
+- ``MONGODB_AUTH_SOURCE`` (default: ``"admin"``)
+
+Note that most of these settings will have to be modified to connect to a MongoDB cluster that runs separately of Tutor, such as `Atlas `__. In particular, the authentication source, mechanism and the SSL connection parameters should not be specified as part of the `host URI `__ but as separate Tutor settings. Supported values for ``MONGODB_AUTH_MECHANISM`` are the same as for pymongo (see the `pymongo documentation `__).
Redis
*****
- ``RUN_REDIS`` (default: ``true``)
- ``REDIS_HOST`` (default: ``"redis"``)
-- ``REDIS_HOST`` (default: ``6379``)
+- ``REDIS_PORT`` (default: ``6379``)
- ``REDIS_USERNAME`` (default: ``""``)
- ``REDIS_PASSWORD`` (default: ``""``)
@@ -157,7 +268,7 @@ SMTP
- ``RUN_SMTP`` (default: ``true``)
- ``SMTP_HOST`` (default: ``"smtp"``)
-- ``SMTP_PORT`` (default: ``25``)
+- ``SMTP_PORT`` (default: ``8025``)
- ``SMTP_USERNAME`` (default: ``""``)
- ``SMTP_PASSWORD`` (default: ``""``)
- ``SMTP_USE_TLS`` (default: ``false``)
@@ -170,22 +281,40 @@ SSL/TLS certificates for HTTPS access
- ``ENABLE_HTTPS`` (default: ``false``)
-By activating this feature, a free SSL/TLS certificate from the `Let's Encrypt `_ certificate authority will be created for your platform. With this feature, **your platform will no longer be accessible in HTTP**. Calls to http urls will be redirected to https url.
+When ``ENABLE_HTTPS`` is ``true``, the whole Open edX platform will be reconfigured to work with "https" URIs. Calls to "http" URIs will be redirected to "https". By default, SSL/TLS certificates will automatically be generated by Tutor (thanks to `Caddy `__) from the `Let's Encrypt `_ certificate authority.
The following DNS records must exist and point to your server::
LMS_HOST (e.g: myopenedx.com)
- preview.LMS_HOST (e.g: preview.myopenedx.com)
+ PREVIEW_LMS_HOST (e.g: preview.myopenedx.com)
CMS_HOST (e.g: studio.myopenedx.com)
Thus, **this feature will (probably) not work in development** because the DNS records will (probably) not point to your development machine.
-The SSL/TLS certificates will automatically be generated and updated by the Caddy proxy server container at runtime. Thus, as of v11.0.0 you no longer have to generate the certificates manually.
+If you would like to perform SSL/TLS termination with your own custom certificates, you will have to keep ``ENABLE_HTTPS=true`` and turn off the Caddy load balancing with ``ENABLE_WEB_PROXY=false``. See the corresponding :ref:`tutorial ` for more information.
.. _customise:
.. _custom_openedx_docker_image:
+Kubernetes
+~~~~~~~~~~
+
+- ``K8S_NAMESPACE`` (default: ``"openedx"``)
+
+This configuration parameter sets the Kubernetes Namespace.
+
+Miscellaneous Project Settings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- ``CONTACT_EMAIL`` (default: ``"contact@{{ LMS_HOST }}"``)
+
+This configuration parameter sets the Contact Email.
+
+- ``PLATFORM_NAME`` (default: ``"My Open edX"``)
+
+This configuration parameter sets the Platform Name.
+
Custom Open edX docker image
----------------------------
@@ -199,17 +328,16 @@ The following sections describe how to modify various aspects of the docker imag
tutor local stop
-The custom image will be used the next time you run ``tutor local quickstart`` or ``tutor local start``. Do not attempt to run ``tutor local restart``! Restarting will not pick up the new image and will continue to use the old image.
+The custom image will be used the next time you run ``tutor local launch`` or ``tutor local start``. Do not attempt to run ``tutor local restart``! Restarting will not pick up the new image and will continue to use the old image.
-openedx Docker Image build arguments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"openedx" Docker image build arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When building the "openedx" Docker image, it is possible to specify a few `arguments `__:
-- ``EDX_PLATFORM_REPOSITORY`` (default: ``"https://github.com/edx/edx-platform.git"``)
-- ``EDX_PLATFORM_VERSION`` (default: ``"open-release/koa.1"``)
-- ``EDX_PLATFORM_VERSION_DATE`` (default: ``"20200227"``)
-- ``NPM_REGISTRY`` (default: ``"https://registry.npmjs.org/"``)
+- ``EDX_PLATFORM_REPOSITORY`` (default: ``"{{ EDX_PLATFORM_REPOSITORY }}"``)
+- ``EDX_PLATFORM_VERSION`` (default: ``"{{ EDX_PLATFORM_VERSION }}"``, which if unset defaults to ``{{ OPENEDX_COMMON_VERSION }}``)
+- ``NPM_REGISTRY`` (default: ``"{{ NPM_REGISTRY }}"``)
These arguments can be specified from the command line, `very much like Docker `__. For instance::
@@ -218,56 +346,27 @@ These arguments can be specified from the command line, `very much like Docker <
Adding custom themes
~~~~~~~~~~~~~~~~~~~~
-Comprehensive theming is enabled by default, but only the default theme is compiled. `Indigo `__ is a better, ready-to-run theme which you can start using today.
-
-To compile your own theme, add it to the ``env/build/openedx/themes/`` folder::
-
- git clone https://github.com/me/myopenedxtheme.git "$(tutor config printroot)/env/build/openedx/themes/myopenedxtheme"
-
-The ``themes`` folder should have the following structure::
-
- openedx/themes/
- mycustomtheme1/
- cms/
- ...
- lms/
- ...
- mycustomtheme2/
- ...
-
-Then you must rebuild the openedx Docker image::
-
- tutor images build openedx
-
-Finally, you should enable your theme with the :ref:`settheme command `.
+See :ref:`the corresponding tutorial `.
.. _custom_extra_xblocks:
Installing extra xblocks and requirements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Would you like to include custom xblocks, or extra requirements to your Open edX platform? Additional requirements can be added to the ``env/build/openedx/requirements/private.txt`` file. For instance, to include the `polling xblock from Opencraft `_::
+Would you like to include custom xblocks, or extra requirements to your Open edX platform? Additional requirements can be added to the ``OPENEDX_EXTRA_PIP_REQUIREMENTS`` parameter in the :ref:`config file `. For instance, to include the `polling xblock from Opencraft `_::
- echo "git+https://github.com/open-craft/xblock-poll.git" >> "$(tutor config printroot)/env/build/openedx/requirements/private.txt"
+ tutor config save --append OPENEDX_EXTRA_PIP_REQUIREMENTS=git+https://github.com/open-craft/xblock-poll.git
Then, the ``openedx`` docker image must be rebuilt::
tutor images build openedx
-To install xblocks from a private repository that requires authentication, you must first clone the repository inside the ``openedx/requirements`` folder on the host::
-
- git clone git@github.com:me/myprivaterepo.git "$(tutor config printroot)/env/build/openedx/requirements/myprivaterepo"
-
-Then, declare your extra requirements with the ``-e`` flag in ``openedx/requirements/private.txt``::
-
- echo "-e ./myprivaterepo" >> "$(tutor config printroot)/env/build/openedx/requirements/private.txt"
-
.. _edx_platform_fork:
Running a fork of ``edx-platform``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You may want to run your own flavor of edx-platform instead of the `official version `_. To do so, you will have to re-build the openedx image with the proper environment variables pointing to your repository and version::
+You may want to run your own flavor of edx-platform instead of the `official version `_. To do so, you will have to re-build the openedx image with the proper environment variables pointing to your repository and version::
tutor images build openedx \
--build-arg EDX_PLATFORM_REPOSITORY=https://mygitrepo/edx-platform.git \
@@ -279,58 +378,28 @@ Note that your edx-platform version must be a fork of the latest release **tag**
If you don't create your fork from this tag, you *will* have important compatibility issues with other services. In particular:
-- Do not try to run a fork from an older (pre-Koa) version of edx-platform: this will simply not work.
+- Do not try to run a fork from an older (pre-Redwood) version of edx-platform: this will simply not work.
- Do not try to run a fork from the edx-platform master branch: there is a 99% probability that it will fail.
-- Do not try to run a fork from the open-release/koa.master branch: Tutor will attempt to apply security and bug fix patches that might already be included in the open-release/koa.master but which were not yet applied to the latest release tag. Patch application will thus fail if you base your fork from the open-release/koa.master branch.
+- Do not try to run a fork from the open-release/redwood.master branch: Tutor will attempt to apply security and bug fix patches that might already be included in the open-release/redwood.master but which were not yet applied to the latest release tag. Patch application will thus fail if you base your fork from the open-release/redwood.master branch.
.. _i18n:
-Adding custom translations
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you are not running Open edX in English, chances are that some strings will not be properly translated. In most cases, this is because not enough contributors have helped translate Open edX in your language. It happens! With Tutor, available translated languages include those that come bundled with `edx-platform `__ as well as those from `openedx-i18n `__.
-
-Tutor offers a relatively simple mechanism to add custom translations to the openedx Docker image. You should create a folder that corresponds to your language code in the "build/openedx/locale" folder of the Tutor environment. This folder should contain a "LC_MESSAGES" folder. For instance::
-
- mkdir -p "$(tutor config printroot)/env/build/openedx/locale/fr/LC_MESSAGES"
-
-The language code should be similar to those used in edx-platform or openedx-i18n (see links above).
-
-Then, add a "django.po" file there that will contain your custom translations::
-
- msgid "String to translate"
- msgstr "δ½ ηΏ»θ―ηδΈθ₯Ώ la traduction de votre bidule"
-
-The "String to translate" part should match *exactly* the string that you would like to translate. You cannot make it up! The best way to find this string is to copy-paste it from the `upstream django.po file for the English language `__.
-
-If you cannot find the string to translate in this file, then it means that you are trying to translate a string that is used in some piece of javascript code. Those strings are stored in a different file named "djangojs.po". You can check it out `in the edx-platform repo as well `__. Your custom javascript strings should also be stored in a "djangojs.po" file that should be placed in the same directory.
-
-To recap, here is an example. To translate a few strings in French, both from django.po and djangojs.po, we would have the following file hierarchy::
-
- $(tutor config printroot)/env/build/openedx/locale/
- fr/
- LC_MESSAGES/
- django.po
- djangojs.po
-
-With django.po containing::
-
- msgid "It works! Powered by Open edX{registered_trademark}"
- msgstr "Γa marche ! PropulsΓ© by Open edX{registered_trademark}"
-
-And djangojs.po::
+Getting and customizing Translations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- msgid "%(num_points)s point possible (graded, results hidden)"
- msgid_plural "%(num_points)s points possible (graded, results hidden)"
- msgstr[0] "%(num_points)s point possible (notΓ©, rΓ©sultats cachΓ©s)"
- msgstr[1] "%(num_points)s points possibles (notΓ©s, rΓ©sultats cachΓ©s)"
+Tutor builds images with the latest translations using the ``atlas pull`` `command `_.
-Then you will have to re-build the openedx Docker image::
+By default the translations are pulled from the `openedx-translations repository `_
+from the ``ATLAS_REVISION`` branch. You can use custom translations on your fork of the openedx-translations repository by setting the following configuration parameters:
- tutor images build openedx openedx-dev
+- ``ATLAS_REVISION`` (default: ``"main"`` on nightly and ``"{{ OPENEDX_COMMON_VERSION }}"`` if a named release is used)
+- ``ATLAS_REPOSITORY`` (default: ``"openedx/openedx-translations"``). There's a feature request to `support GitLab and other providers `_.
+- ``ATLAS_OPTIONS`` (default: ``""``) Pass additional arguments to ``atlas pull``. Refer to the `atlas documentations `_ for more information.
-Beware that this will take a long time! Unfortunately it's difficult to accelerate this process, as translation files need to be compiled prior to collecting the assets. In development it's possible to accelerate the iteration loop -- but that exercise is left to the reader.
+If you are not running Open edX in English (``LANGUAGE_CODE`` default: ``"en"``), chances are that some strings will not be properly translated. In most cases, this is because not enough contributors have helped translate Open edX into your language. It happens!
+With ``atlas``, it's possible to add custom translations by either `contributing to the Translations project in Transifex `_ or forking the `openedx-translations repository `_
+and making custom changes as explained in `the repository docs `_.
Running a different ``openedx`` Docker image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -343,4 +412,18 @@ By default, Tutor runs the `overhangio/openedx `.)
-The customised Docker image tag value will then be used by Tutor to run the platform, for instance when running ``tutor local quickstart``.
+The customised Docker image tag value will then be used by Tutor to run the platform, for instance when running ``tutor local launch``.
+
+
+Passing custom docker build options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can set a limited set of Docker build options via ``tutor images build`` command. In some situations it might be necessary to tweak the docker build command, ex- setting up build caching using buildkit.
+In these situations, you can set ``--docker-arg`` flag in the ``tutor images build`` command. You can set any `supported options `_ in the docker build command, For example::
+
+ tutor images build openedx \
+ --build-arg BUILDKIT_INLINE_CACHE=1 \
+ --docker-arg="--cache-from" \
+ --docker-arg="docker.io/myusername/openedx:mytag"
+
+This will result in passing the ``--cache-from`` option with the value ``docker.io/myusername/openedx:mytag`` to the docker build command.
diff --git a/docs/dev.rst b/docs/dev.rst
index e2a42995e0..4d6c2249e2 100644
--- a/docs/dev.rst
+++ b/docs/dev.rst
@@ -5,37 +5,84 @@ Open edX development
In addition to running Open edX in production, Tutor can be used for local development of Open edX. This means that it is possible to hack on Open edX without setting up a Virtual Machine. Essentially, this replaces the devstack provided by edX.
-The following commands assume you have previously launched a :ref:`local ` Open edX platform. If you have not done so already, you should run::
+For detailed explanations on how to work on edx-platform and its dependencies, see the :ref:`edx_platform` tutorial.
- tutor local quickstart
+.. _edx_platform_dev_env:
-In order to run the platform in development mode, you **must** answer no ("n") to the question "Are you configuring a production platform".
+First-time setup
+----------------
-Note that the local.overhang.io `domain `__ and its `subdomains `__ all point to 127.0.0.1. This is just a domain name that was setup to conveniently access a locally running Open edX platform.
+Firstly, either :ref:`install Tutor ` (for development against the named releases of Open edX) or :ref:`install Tutor Nightly ` (for development against Open edX's master branches).
-Once the local platform has been configured, you should stop it so that it does not interfere with the development environment::
+Then, optionally, tell Tutor to use a local fork of edx-platform::
- tutor local stop
+ tutor mounts add ./edx-platform
-Finally, you should build the ``openedx-dev`` docker image::
+Then, launch the developer platform setup process::
tutor images build openedx-dev
+ tutor dev launch
-This ``openedx-dev`` development image differs from the ``openedx`` production image:
+This will perform several tasks. It will:
-- The user that runs inside the container has the same UID as the user on the host, in order to avoid permission problems inside mounted volumes (and in particular in the edx-platform repository).
-- Additional python and system requirements are installed for convenient debugging: `ipython `__, `ipdb `__, vim, telnet.
-- The edx-platform `development requirements `__ are installed.
+* build the "openedx-dev" Docker image, which is based on the "openedx" production image but is `specialized for developer usage`_ (eventually with your fork),
+* stop any existing locally-running Tutor containers,
+* disable HTTPS,
+* set ``LMS_HOST`` to `local.edly.io `_ (a convenience domain that simply `points at 127.0.0.1 `_),
+* prompt for a platform details (with suitable defaults),
+* start LMS, CMS, supporting services, and any plugged-in services,
+* ensure databases are created and migrated, and
+* run service initialization scripts, such as service user creation and Waffle configuration.
-Since the ``openedx-dev`` is based upon the ``openedx`` docker image, it should be re-built every time the ``openedx`` docker image is modified.
+Additionally, when a local clone of edx-platform is bind-mounted, it will:
-Run a local development webserver
----------------------------------
+* re-run setup.py,
+* clean-reinstall Node modules, and
+* regenerate static assets.
-::
+Once setup is complete, the platform will be running in the background:
- tutor dev runserver lms # Access the lms at http://local.overhang.io:8000
- tutor dev runserver cms # Access the cms at http://studio.local.overhang.io:8001
+* LMS will be accessible at `http://local.edly.io:8000 `_.
+* CMS will be accessible at `http://studio.local.edly.io:8001 `_.
+* Plugged-in services should be accessible at their documented URLs.
+
+Now, use the ``tutor dev ...`` command-line interface to manage the development environment. Some common commands are described below.
+
+.. note::
+
+ If you've added your edx-platform to the bind-mounted folders, you can remove at any time by running::
+
+ tutor mounts remove ./edx-platform
+
+ At any time, check your configuration by running::
+
+ tutor mounts list
+
+ Read more about bind-mounts :ref:`below `.
+
+Stopping the platform
+---------------------
+
+To bring down the platform's containers, simply run::
+
+ tutor dev stop
+
+Starting the platform back up
+-----------------------------
+
+Once first-time setup has been performed with ``launch``, the platform can be started going forward with the lighter-weight ``start -d`` command, which brings up containers *detached* (that is: in the background), but does not perform any initialization tasks::
+
+ tutor dev start -d
+
+Or, to start with platform with containers *attached* (that is: in the foreground, the current terminal), omit the ``-d`` flag::
+
+ tutor dev start
+
+When running containers attached, stop the platform with ``Ctrl+c``, or switch to detached mode using ``Ctrl+z``.
+
+Finally, the platform can also be started back up with ``launch``. It will take longer than ``start``, but it will ensure that config is applied, databases are provisioned & migrated, plugins are fully initialized, and (if applicable) the bind-mounted edx-platform is set up. Notably, ``launch`` is idempotent, so it is always safe to run it again without risk to data. Including the ``--pullimages`` flag will also ensure that container images are up-to-date::
+
+ tutor dev launch --pullimages
Running arbitrary commands
--------------------------
@@ -52,136 +99,160 @@ To open a python shell in the LMS or CMS, run::
You can then import edx-platform and django modules and execute python code.
-To collect assets, you can use the ``openedx-assets`` command that ships with Tutor::
+To rebuild assets, you can run the ``build-dev`` NPM script that comes with edx-platform::
- tutor dev run lms openedx-assets --env=dev
+ tutor dev run lms npm run build-dev
-Point to a local edx-platform
------------------------------
-If you have one, you can point to a local version of `edx-platform `_ on your host machine. To do so, pass a ``-v/--volume`` option to the ``run`` and runserver commands. For instance::
+.. _specialized for developer usage:
- tutor dev run -v /path/to/edx-platform:/openedx/edx-platform lms bash
+Rebuilding the openedx-dev image
+--------------------------------
-If you don't want to rewrite this option every time, you can define a command alias::
+The ``openedx-dev`` Docker image is based on the same ``openedx`` image used by ``tutor local ...`` to run LMS and CMS. However, it has a few differences to make it more convenient for developers:
- alias tutor-dev-run-lms="tutor dev run -v /path/to/edx-platform:/openedx/edx-platform lms"
+- The user that runs inside the container has the same UID as the user on the host, to avoid permission problems inside mounted volumes (and in particular in the edx-platform repository).
+- Additional Python and system requirements are installed for convenient debugging: `ipython `__, `ipdb `__, vim, telnet.
+- The edx-platform `development requirements `__ are installed.
-For technical reasons, the ``-v`` option is only supported for the ``run`` and ``runserver`` commands. With these commands, only one service is started. But there are cases where you may want to launch and debug a complete Open edX platform with ``tutor dev start`` and mount a custom edx-platform fork. For instance, this might be needed when testing the interaction between multiple services. To do so, you should create a ``docker-compose.override.yml`` file that will specify a custom volume to be used with all ``dev`` commands::
- vim "$(tutor config printroot)/env/dev/docker-compose.override.yml"
+If you are using a custom ``openedx`` image, then you will need to rebuild ``openedx-dev`` every time you modify ``openedx``. To so, run::
-Then, add the following content::
+ tutor images build openedx-dev
- version: "3.7"
- services:
- lms:
- volumes:
- - /path/to/edx-platform/:/openedx/edx-platform
- cms:
- volumes:
- - /path/to/edx-platform/:/openedx/edx-platform
- lms-worker:
- volumes:
- - /path/to/edx-platform/:/openedx/edx-platform
- cms-worker:
- volumes:
- - /path/to/edx-platform/:/openedx/edx-platform
+Alternatively, the image will be automatically rebuilt every time you run::
-This override file will be loaded when running any ``tutor dev ..`` command. The edx-platform repo mounted at the specified path will be automaticall mounted inside all LMS and CMS containers. With this file, you should no longer specify the ``-v`` option from the command line with the ``run`` or ``runserver`` commands.
+ tutor dev launch
-**Note:** containers are built on the Koa release. If you are working on a different version of Open edX, you will have to rebuild the ``openedx`` docker images with the version. See the :ref:`fork edx-platform section `.
-Prepare the edx-platform repo
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. _bind_mounts:
-In order to run a fork of edx-platform, dependencies need to be properly installed and assets compiled in that repo. To do so, run::
+Sharing directories with containers
+-----------------------------------
- tutor dev run -v /path/to/edx-platform:/openedx/edx-platform lms bash
- pip install --requirement requirements/edx/development.txt
- python setup.py install
- npm install
- openedx-assets build --env=dev
+It may sometimes be convenient to mount container directories on the host, for instance: for editing and debugging. Tutor provides different solutions to this problem.
-Debug edx-platform
-~~~~~~~~~~~~~~~~~~
+.. _persistent_mounts:
-To debug a local edx-platform repository, add a ``import ipdb; ipdb.set_trace()`` breakpoint anywhere in your code and run::
+Persistent bind-mounted volumes with ``tutor mounts``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- tutor dev runserver -v /path/to/edx-platform:/openedx/edx-platform lms
+``tutor mounts`` is a set of Tutor command to manage bind-mounted host directories. Directories are mounted `both` at build time and run time:
-XBlock and edx-platform plugin development
-------------------------------------------
+- At build time: some of the host directories will be added the `Docker build context `__. This makes it possible to transparently build a Docker image using a locally checked-out repository.
+- At run time: host directories will be bind-mounted in running containers, using either an automatic or a manual configuration.
-In some cases you will have to develop features for packages that are pip-installed next to edx-platform. This is quite easy with Tutor. Just add your packages to the ``$(tutor config printroot)/env/build/openedx/requirements/private.txt`` file. To avoid re-building the openedx Docker image at every change, you should add your package in editable mode. For instance::
- echo "-e ./mypackage" >> "$(tutor config printroot)/env/build/openedx/requirements/private.txt"
+After some directories have been added with ``tutor mounts add``, all ``tutor dev`` and ``tutor local`` commands will make use of these bind-mount volumes.
-The ``requirements`` folder should have the following content::
+Values passed to ``tutor mounts add ...`` can take one of two forms. The first is explicit::
- env/build/openedx/requirements/
- private.txt
- mypackage/
- setup.py
- ...
+ tutor mounts add lms:/path/to/edx-platform:/openedx/edx-platform
-You will have to re-build the openedx Docker image once::
+The second is implicit::
- tutor images build openedx
+ tutor mounts add /path/to/edx-platform
-You should then run the development server as usual, with ``runserver``. Every change made to the ``mypackage`` folder will be picked up and the development server will be automatically reloaded.
+With the explicit form, the value means "bind-mount the host folder /path/to/edx-platform to /openedx/edx-platform in the lms container at run time".
-.. _theming:
+If you use the explicit format, you will quickly realise that you usually want to bind-mount folders in multiple containers at a time. For instance, you will want to bind-mount the edx-platform repository in the "cms" container, but also the "lms-worker" and "cms-worker" containers. To do that, write instead::
-Customised themes
------------------
+ # each service is added to a coma-separated list
+ tutor mounts add lms,cms,lms-worker,cms-worker:/path/to/edx-platform:/openedx/edx-platform
-With Tutor, it's pretty easy to develop your own themes. Start by placing your files inside the ``env/build/openedx/themes`` directory. For instance, you could start from the ``edx.org`` theme present inside the ``edx-platform`` repository::
+This command line is a bit cumbersome. In addition, with this explicit form, the edx-platform repository will *not* be added to the build context at build time. But Tutor can be smart about bind-mounting folders to the right containers in the right place when you use the implicit form of the ``tutor mounts add`` command. For instance, the following implicit form can be used instead of the explicit form above::
- cp -r /path/to/edx-platform/themes/edx.org "$(tutor config printroot)/env/build/openedx/themes/"
+ tutor mounts add /path/to/edx-platform
-.. warning::
- You should not create a soft link here. If you do, it will trigger a ``Theme not found in any of the themes dirs`` error. This is because soft links are not properly resolved from inside docker containers.
+With this implicit form, the edx-platform repo will be bind-mounted in the containers at run time, just like with the explicit form. But in addition, the edx-platform will also automatically be added to the Docker image at build time.
-Then, run a local webserver::
+To check whether you have used the correct syntax, you should run ``tutor mounts list``. This command will indicate whether your folders will be bind-mounted at build time, run time, or both. For instance::
- tutor dev runserver lms
+ $ tutor mounts add /path/to/edx-platform
+ $ tutor mounts list
+ - name: /path/to/edx-platform
+ build_mounts:
+ - image: openedx
+ context: edx-platform
+ - image: openedx-dev
+ context: edx-platform
+ compose_mounts:
+ - service: lms
+ container_path: /openedx/edx-platform
+ - service: cms
+ container_path: /openedx/edx-platform
+ - service: lms-worker
+ container_path: /openedx/edx-platform
+ - service: cms-worker
+ container_path: /openedx/edx-platform
+ - service: lms-job
+ container_path: /openedx/edx-platform
+ - service: cms-job
+ container_path: /openedx/edx-platform
-The LMS can then be accessed at http://local.overhang.io:8000. You will then have to :ref:`enable that theme ` for the development domain names::
+So, when should you *not* be using the implicit form? That would be when Tutor does not know where to bind-mount your host folders. For instance, if you wanted to bind-mount your edx-platform virtual environment located in ``~/venvs/edx-platform``, you should not write ``mounts add ~/venvs/edx-platform``, because that folder would be mounted in a way that would override the edx-platform repository in the container. Instead, you should write::
- tutor dev settheme mythemename local.overhang.io:8000 studio.local.overhang.io:8001
+ tutor mounts add lms:~/venvs/edx-platform:/openedx/venv
-Re-build development docker image (and compile assets)::
+Verify the configuration with the ``list`` command::
- tutor images build openedx-dev
+ $ tutor mounts list
+ - name: lms:~/venvs/edx-platform:/openedx/venv
+ build_mounts: []
+ compose_mounts:
+ - service: lms
+ container_path: /openedx/venv
+
+.. note:: Remember to setup your edx-platform repository for development! See :ref:`edx_platform_dev_env`.
-Watch the themes folders for changes (in a different terminal)::
+Copy files from containers to the local filesystem
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- tutor dev run watchthemes
+Sometimes, you may want to modify some of the files inside a container for which you don't have a copy on the host. A typical example is when you want to troubleshoot a Python dependency that is installed inside the application virtual environment. In such cases, you want to first copy the contents of the virtual environment from the container to the local filesystem. To that end, Tutor provides the ``tutor dev copyfrom`` command. First, copy the contents of the container folder to the local filesystem::
-Make changes to some of the files inside the theme directory: the theme assets should be automatically recompiled and visible at http://local.overhang.io:8000.
+ tutor dev copyfrom lms /openedx/venv ~
-Custom edx-platform settings
-----------------------------
+Then, bind-mount that folder back in the container with the ``MOUNTS`` setting (described :ref:`above `)::
-By default, tutor settings files are mounted inside the docker images at ``/openedx/edx-platform/lms/envs/tutor/`` and ``/openedx/edx-platform/cms/envs/tutor/``. In the various ``dev`` commands, the default ``edx-platform`` settings module is set to ``tutor.development`` and you don't have to do anything to set up these settings.
+ tutor mounts add lms:~/venv:/openedx/venv
-If, for some reason, you want to use different settings, you will need to pass the ``-e SETTINGS=mycustomsettings`` option to each command. Alternatively, you can define the ``TUTOR_EDX_PLATFORM_SETTINGS`` environment variable.
+You can then edit the files in ``~/venv`` on your local filesystem and see the changes live in your "lms" container.
-For instance, let's assume you have created the ``/path/to/edx-platform/lms/envs/mysettings.py`` and ``/path/to/edx-platform/cms/envs/mysettings.py`` modules. These settings should be pretty similar to the following files::
+Manual bind-mount to any directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- $(tutor config printroot)/env/apps/openedx/tutor/lms/development.py
- $(tutor config printroot)/env/apps/openedx/tutor/cms/development.py
+.. warning:: Manually bind-mounting volumes with the ``--volume`` option makes it difficult to simultaneously bind-mount to multiple containers. Also, the ``--volume`` options are not compatible with ``start`` commands. As an alternative, you should consider following the instructions above: :ref:`persistent_mounts`.
-Alternatively, the ``mysettings.py`` files can import the tutor development settings::
+The above solution may not work for you if you already have an existing directory, outside of the "volumes/" directory, which you would like mounted in one of your containers. For instance, you may want to mount your copy of the `edx-platform `__ repository. In such cases, you can simply use the ``-v/--volume`` `Docker option `__::
- # Beginning of mysettings.py
- from .tutor.development import *
+ tutor dev run --volume=/path/to/edx-platform:/openedx/edx-platform lms bash
-You should then specify the settings to use on the host::
+Override docker-compose volumes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- export TUTOR_EDX_PLATFORM_SETTINGS=mysettings
+.. warning:: While the option described below "works", it will only bind-mount directories at run-time. In many cases you really want to bind-mount directories at build-time. For instance: when working on edx-platform requirements. As an alternative, you should consider following the instructions above: :ref:`persistent_mounts`.
+
+Adding items to the ``MOUNTS`` setting effectively adds new bind-mount volumes to the ``docker-compose.yml`` files. But you might want to have more control over your volumes, such as adding read-only options, or customising other fields of the different services. To address these issues, you can create a ``docker-compose.override.yml`` file that will specify custom volumes to be used with all ``dev`` commands::
+
+ vim "$(tutor config printroot)/env/dev/docker-compose.override.yml"
+
+You are then free to bind-mount any directory to any container. For instance, to mount your own edx-platform fork::
+
+ services:
+ lms:
+ volumes:
+ - /path/to/edx-platform:/openedx/edx-platform
+ cms:
+ volumes:
+ - /path/to/edx-platform:/openedx/edx-platform
+ lms-worker:
+ volumes:
+ - /path/to/edx-platform:/openedx/edx-platform
+ cms-worker:
+ volumes:
+ - /path/to/edx-platform:/openedx/edx-platform
-From then on, all ``dev`` commands will use the ``mysettings`` module. For instance::
+This override file will be loaded when running any ``tutor dev ..`` command. The edx-platform repo mounted at the specified path will be automatically mounted inside all LMS and CMS containers.
- tutor dev runserver -v /path/to/edx-platform:/openedx/edx-platform lms
+.. note::
+ The ``tutor local`` commands load the ``docker-compose.override.yml`` file from the ``$(tutor config printroot)/env/local/docker-compose.override.yml`` directory. One-time jobs from initialisation commands load the ``local/docker-compose.jobs.override.yml`` and ``dev/docker-compose.jobs.override.yml``.
diff --git a/docs/cli_download.rst b/docs/download/binary.rst
similarity index 82%
rename from docs/cli_download.rst
rename to docs/download/binary.rst
index a71fd60c79..69c1c75ccf 100644
--- a/docs/cli_download.rst
+++ b/docs/download/binary.rst
@@ -3,4 +3,4 @@
.. parsed-literal::
sudo curl -L "\ https\ ://github.com/overhangio/tutor/releases/download/v\ |tutor_version|/tutor-$(uname -s)_$(uname -m)" -o /usr/local/bin/tutor
- sudo chmod 0755 /usr/local/bin/tutor
+ sudo chmod 0755 /usr/local/bin/tutor
\ No newline at end of file
diff --git a/docs/download/pip.rst b/docs/download/pip.rst
new file mode 100644
index 0000000000..015dce421e
--- /dev/null
+++ b/docs/download/pip.rst
@@ -0,0 +1,3 @@
+.. parsed-literal::
+
+ pip install "tutor[full]"
diff --git a/docs/extra.rst b/docs/extra.rst
deleted file mode 100644
index 5da269bb85..0000000000
--- a/docs/extra.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. _extra:
-
-Extra features
-==============
-
-.. _webui:
-
-Web UI
-------
-
-Tutor comes with a web user interface (UI) that allows you to administer your Open edX platform remotely. It's especially convenient for remote administration of the platform.
-
-Launching the web UI
-~~~~~~~~~~~~~~~~~~~~
-
-::
-
- tutor webui start
-
-You can then access the interface at http://localhost:3737, or http://youserverurl:3737.
-
-.. image:: img/webui.png
-
-All ``tutor`` commands can be executed from this web UI: you just don't need to prefix the commands with ``tutor``. For instance, to deploy a local Open edX instance, run::
-
- local quickstart
-
-instead of ``tutor local quickstart``.
-
-Authentication
-~~~~~~~~~~~~~~
-
-**WARNING** Once you launch the web UI, it is accessible by everyone, which means that your Open edX platform is at risk. If you are planning to leave the web UI up for a long time, you should setup a user and password for authentication::
-
- tutor webui configure
-
-.. _mobile:
-
-Mobile Android application
---------------------------
-
-With Tutor, you can build an Android mobile application for your platform. To build the application in debug mode, run::
-
- tutor android build debug
-
-The ``.apk`` file will then be available in ``$(tutor config printroot)/data/android``. Transfer it to an Android phone to install the application. You should be able to sign in and view available courses.
-
-Building a custom Android app
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Android app is built from the `official edx-app-android repository `__. To change this repository or the app version, you can simply build a different docker image with::
-
- tutor images build \
- --build-arg ANDROID_APP_REPOSITORY=https://github.com/mycustomfork/edx-app-android \
- --build-arg ANDROID_APP_VERSION=master \
- android
-
-Releasing an Android app
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Note**: this is an untested feature.
-
-Releasing an Android app on the Play Store requires to build the app in release mode. To do so, edit the ``$TUTOR_ROOT/config.yml`` configuration file and define the following variables::
-
- ANDROID_RELEASE_STORE_PASSWORD
- ANDROID_RELEASE_KEY_PASSWORD
- ANDROID_RELEASE_KEY_ALIAS
-
-Then, place your keystore file in ``$(tutor config printroot)/env/android/app.keystore``. Finally, build the application with::
-
- tutor android build release
-
-Customising the Android app
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Customising the application, such as the logo or the background image, is currently not supported. If you are interested by this feature, please tell us about it in the Tutor `discussion forums `_.
diff --git a/docs/faq.rst b/docs/faq.rst
index bf82a7199a..373519f9c0 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -6,58 +6,40 @@ FAQ
What is Tutor?
--------------
-Tutor is an open source distribution of `Open edX `_. It uses the original code from the various Open edX repositories, such as `edx-platform `_, `cs_comments_service `_, etc. and packages everything in a way that makes it very easy to install, administer and upgrade Open edX. In particular, all services are run inside Docker containers.
+Tutor is an open source distribution of the `Open edX platform `_. It uses the original code from the various Open edX repositories, such as `edx-platform `_, `cs_comments_service `_, etc. and packages everything in a way that makes it very easy to install, administer and upgrade an Open edX installation. In particular, all services are run inside Docker containers.
-Tutor makes it possible to deploy Open edX locally, with `docker-compose `_ or on an existing `Kubernetes cluster `_.
+Tutor makes it possible to deploy an Open edX instance locally, with `docker-compose `_ or on an existing `Kubernetes cluster `_. Want to learn more? Take a look at the :ref:`getting started concepts `.
What is the purpose of Tutor?
-----------------------------
-To make it possible to deploy, administer and upgrade Open edX anywhere, easily.
+To make it possible to deploy, administer and upgrade an Open edX installation anywhere, easily.
.. _native:
-What's the difference with the official "native" installation?
---------------------------------------------------------------
-
-The `native installation `_ maintained by edX relies on `Ansible scripts `_ to deploy Open edX on one or multiple servers. These scripts suffer from a couple issues that Tutor tries to address:
-
-1. Complexity: the scripts contain close to 35k lines of code spread over 780 files. They are really hard to understand, debug, and modify, and they are extremly slow. As a consequence, Open edX is often wrongly perceived as a project that is overly complex to manage. In contrast, Tutor generates mostly ``Dockerfile`` and ``docker-compose.yml`` files that make it easy to understand what is going on. Also, the whole installation should take about 10 minutes.
-2. Isolation from the OS: Tutor barely needs to touch your server because the entire platform is packaged inside Docker containers. You are thus free to run other services on your server without fear of indirectly crashing your Open edX platform.
-3. Compatibility: Open edX is only compatible with Ubuntu 16.04, but that shouldn't mean you are forced to run this specific OS. With Tutor, you can deploy Open edX on just any server you like: Ubuntu 18.04, Red Hat, Debian... All docker-compatible platforms are supported.
-4. Security: because you are no longer bound to a single OS, with Tutor you are now free to install security-related upgrades as soon as they become available.
-5. Portability: Tutor makes it easy to move your platform from one server to another. Just zip-compress your Tutor project root, send it to another server and you're done.
-
-There are also many features that are not included in the native installation, such as a :ref:`web user interface ` for remotely installing the platform, :ref:`Kubernetes deployment `, additional languages, etc. You'll discover these differences as you explore Tutor :)
-
-What's the difference with the official devstack?
+What's the difference between Tutor and Devstack?
-------------------------------------------------
-The `devstack `_ is meant for development only, not for production deployment. Tutor can be used both for production deployment and :ref:`locally hacking on Open edX `.
+The `devstack `_ was a tool meant only for local development; it is now deprecated, in favor of Tutor. Tutor can be used both for production deployment and :ref:`locally hacking on Open edX `.
-Is Tutor officially supported by edX?
--------------------------------------
+Is Tutor officially supported by the Open edX project?
+------------------------------------------------------
-No. Tutor is developed independently from edX. That means that the folks at edX.org are *not* responsible for troubleshooting issues of this project. Please don't bother Ned ;-)
+As of the Open edX Maple release (December 9th 2021), Tutor is the only community-supported installation method for the Open edX platform: see the `official installation instructions `__.
What features are missing from Tutor?
-------------------------------------
-Tutor tries very hard to support all major Open edX features, notably in the form of :ref:`plugins `. In particular, the discovery and ecommerce services, once unavailable in Tutor, can now be easily installed via plugins. If you are interested in sponsoring the development of a new plugin, please `get in touch `__!
+Tutor tries very hard to support all major Open edX platform features, notably in the form of :ref:`plugins `. If you are interested in sponsoring the development of a new plugin, please `get in touch `__!
-It should be noted that the `Analytics `__ stack is currently unsupported, and will likely stay so in the future, as it would require a tremendous amount of work to containerize all the components. For generating great-looking analytics reports, we recommend the `Figures plugin `__.
+It should be noted that the `Insights `__ stack is currently unsupported, because of its complexity, lack of support, and extensibility. To replace it, Edly has developed `Cairn `__ the next-generation analytics solution for the Open edX platform, and the Open edX community is working on a new analytics project, in beta as of the Redwood release, called `Aspects `_. You should check them out π
Are there people already running this in production?
----------------------------------------------------
-Yes, many of them. There is no way to count precisely how many running Open edX platforms were deployed with Tutor, but from feedback collected directly from real users, there must be dozens, if not hundreds. Tutor is also used by some Open edX providers who are hosting platforms for their customers.
-
-Why should I trust software written by some random guy on the Internet?
------------------------------------------------------------------------
+Yes: system administrators all around the world use Tutor to run their Open edX platforms, from single-class school teachers to renowned universities, Open edX SaaS providers, and nation-wide learning platforms.
-You shouldn't :) Tutor is actively maintained by `Overhang.IO `_, a France-based company founded by `RΓ©gis Behmo `_. RΓ©gis has been working on Tutor since early 2018; he has been a contributor of the Open edX project since 2015. In particular, he has worked for 2 years at `FUN-MOOC `_, one of the top 5 largest Open edX platforms in the world. He presented several talks at the Open edX conferences:
+Why should I trust your software?
+---------------------------------
-- *Deploying a robust, scalable Open edX platform in 1 click (or less) with Tutor*, March 2019 (`video `_, `slides `_)
-- *Videofront: a Self-Hosted YouTube*, June 2017 (`video `__, `slides `__)
-- *Open edX 101: A Source Code Review*, June 2016 (`video `__, `slides `__)
-- *FUN: Life in the Avant-Garde*, Oct. 2015 (`video `__, `slides `__)
+You shouldn't :) Tutor is actively maintained by `Edly `__, a US-based ed-tech company facilitating over 40 million learners worldwide through its eLearning solutions. With a credible engineering team that has won clients' hearts globally led by `RΓ©gis Behmo `__, Tutor has empowered numerous edtech ventures over the years. Additionally, Tutor is a `community-led project `__ with many contributions from its :ref:`project maintainers `.
diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst
index b33914dbe8..3341091c78 100644
--- a/docs/gettingstarted.rst
+++ b/docs/gettingstarted.rst
@@ -5,8 +5,8 @@ Getting started
.. toctree::
:maxdepth: 2
-
+
+ install
intro
quickstart
- install
- whatnext
\ No newline at end of file
+ whatnext
diff --git a/docs/img/favicon.png b/docs/img/favicon.png
index 662c44611f..3e169ce6ee 100644
Binary files a/docs/img/favicon.png and b/docs/img/favicon.png differ
diff --git a/docs/img/launch.webp b/docs/img/launch.webp
new file mode 100644
index 0000000000..1520accd15
Binary files /dev/null and b/docs/img/launch.webp differ
diff --git a/docs/img/logo.png b/docs/img/logo.png
deleted file mode 100644
index fa447e3eda..0000000000
Binary files a/docs/img/logo.png and /dev/null differ
diff --git a/docs/img/portainer.png b/docs/img/portainer.png
new file mode 100644
index 0000000000..7b9b6992a3
Binary files /dev/null and b/docs/img/portainer.png differ
diff --git a/docs/img/quickstart.gif b/docs/img/quickstart.gif
deleted file mode 100644
index 901f9e50de..0000000000
Binary files a/docs/img/quickstart.gif and /dev/null differ
diff --git a/docs/img/tutor-logo.png b/docs/img/tutor-logo.png
deleted file mode 100644
index 59ea2c4237..0000000000
Binary files a/docs/img/tutor-logo.png and /dev/null differ
diff --git a/docs/img/webui.png b/docs/img/webui.png
deleted file mode 100644
index 4f52c60058..0000000000
Binary files a/docs/img/webui.png and /dev/null differ
diff --git a/docs/index.rst b/docs/index.rst
index c9d7b089ac..4efaf54ff6 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,10 +1,13 @@
+Tutor: the Docker-based Open edX distribution designed for peace of mind
+========================================================================
+
.. include:: ../README.rst
:start-after: _readme_intro_start:
:end-before: _readme_intro_end:
-
-.. image:: ./img/quickstart.gif
- :alt: Tutor local quickstart
- :target: https://terminalizer.com/view/91b0bfdd557
+
+.. image:: ./img/launch.webp
+ :alt: Tutor local launch
+ :target: https://www.terminalizer.com/view/3a8d55835686
----------------------------------
@@ -22,12 +25,23 @@
gettingstarted
run
configuration
- plugins
- extra
+ plugins/index
+ reference/index
+ tutorials/index
troubleshooting
tutor
faq
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Project links
+
+ Source code
+ Community forums
+ Pypi releases
+ Changelog
+
Source code
-----------
@@ -36,11 +50,11 @@ The complete source code for Tutor is available on Github: https://github.com/ov
.. include:: ../README.rst
:start-after: _readme_support_start:
:end-before: _readme_support_end:
-
+
.. include:: ../README.rst
:start-after: _readme_contributing_start:
:end-before: _readme_contributing_end:
-
+
License
-------
@@ -48,6 +62,6 @@ This work is licensed under the terms of the `GNU Affero General Public License
The AGPL license covers the Tutor code, including the Dockerfiles, but not the content of the Docker images which can be downloaded from https://hub.docker.com. Software other than Tutor provided with the docker images retain their original license.
-The Tutor plugin system is licensed under the terms of the `Apache License, Version 2.0 `__.
+The Tutor plugin and hooks system is licensed under the terms of the `Apache License, Version 2.0 `__.
-The :ref:`Tutor Web UI ` depends on the `Gotty `_ binary, which is provided under the terms of the `MIT license `_.
+Β© 2021 Tutor is a registered trademark of SASU NULI NULI. All Rights Reserved.
diff --git a/docs/install.rst b/docs/install.rst
index 4d27a0d019..b5d8ccadb3 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -1,23 +1,24 @@
.. _install:
-Install Tutor
-=============
+Installing Tutor
+================
.. _requirements:
Requirements
------------
-* Supported OS: Tutor runs on any 64-bit, UNIX-based system. It was also reported to work on Windows.
+* Supported OS: Tutor runs on any 64-bit, UNIX-based OS. It was also reported to work on Windows (with `WSL 2 `__).
+* Architecture: Both AMD64 and ARM64 are supported.
* Required software:
- - `Docker `__: v18.06.0+
- - `Docker Compose `__: v1.22.0+
+ - `Docker `__: v24.0.5+ (with BuildKit 0.11+)
+ - `Docker Compose `__: v2.0.0+
.. warning::
Do not attempt to simply run ``apt-get install docker docker-compose`` on older Ubuntu platforms, such as 16.04 (Xenial), as you will get older versions of these utilities.
-* Ports 80 and 443 should be open. If other web services run on these ports, check the section on :ref:`how to setup a web proxy `.
+* Ports 80 and 443 should be open. If other web services run on these ports, check the tutorial on :ref:`how to setup a web proxy `.
* Hardware:
- Minimum configuration: 4 GB RAM, 2 CPU, 8 GB disk space
@@ -26,56 +27,56 @@ Requirements
.. note::
On Mac OS, by default, containers are allocated 2 GB of RAM, which is not enough. You should follow `these instructions from the official Docker documentation `__ to allocate at least 4-5 GB to the Docker daemon. If the deployment fails because of insufficient memory during database migrations, check the :ref:`relevant section in the troubleshooting guide `.
-.. _install_binary:
+Download
+--------
-Direct binary download
-----------------------
+Choose **one** of the installation methods below. If you install Tutor in different ways, you will end up with multiple ``tutor`` executables, which is going to be very confusing. At any time, you can check the path to your ``tutor`` executable by running ``which tutor``.
-The latest binaries can be downloaded from https://github.com/overhangio/tutor/releases. From the command line:
+Python package
+~~~~~~~~~~~~~~
-.. include:: cli_download.rst
+.. include:: download/pip.rst
-This is the simplest and recommended installation method for most people. Note however that you will not be able to use custom plugins with this pre-compiled binary. The only plugins you can use with this approach are those that are already bundled with the binary: see the :ref:`existing plugins `.
+Check the "tutor" package on Pypi: https://pypi.org/project/tutor. You will need Python >= 3.6 with pip and the libyaml development headers. On Ubuntu, these requirements can be installed by running::
-.. _install_source:
+ sudo apt install python3 python3-pip libyaml-dev
-Alternative installation methods
---------------------------------
+.. _install_binary:
-If you would like to inspect the Tutor source code, you are most welcome to install Tutor from `Pypi `_ or directly from `the Github repository `_. You will need python >= 3.6 with pip and the libyaml development headers. On Ubuntu, these requirements can be installed by running::
+Binary release
+~~~~~~~~~~~~~~
- sudo apt install python3 python3-pip libyaml-dev
+The latest binaries can be downloaded from https://github.com/overhangio/tutor/releases. From the command line:
-Installing from pypi
-~~~~~~~~~~~~~~~~~~~~
+.. include:: download/binary.rst
-::
+This is the simplest and recommended installation method for most people who do not have Python 3 on their machine. Note however that **you will not be able to use custom plugins** with this pre-compiled binary. The only plugins you can use with this approach are those that are already bundled with the binary: see the :ref:`existing plugins `.
- pip install tutor-openedx
+.. _install_source:
Installing from source
~~~~~~~~~~~~~~~~~~~~~~
-::
+To inspect the Tutor source code, install Tutor from `the Github repository `__::
git clone https://github.com/overhangio/tutor
cd tutor
pip install -e .
-DNS records
------------
+Configuring DNS records
+-----------------------
-When running a server in production, it is necessary to define `DNS records `__ which will make it possible to access your Open edX platform by name in your browser. The precise procedure to create DNS records vary from one provider to the next and is beyond the scope of these docs. You should create a record of type A with a name equal to your LMS hostname (given by ``tutor config printvalue LMS_HOST``) and a value that indicates the IP address of your server. Applications other than the LMS, such as the studio, ecommerce, etc. typically reside in subdomains of the LMS. Thus, you should also create a CNAME record to point all subdomains of the LMS to the LMS_HOST.
+When running a server in production, it is necessary to define `DNS records `__ which will make it possible to access your Open edX platform by name in your browser. The precise procedure to create DNS records varies from one provider to the next and is beyond the scope of these docs. You should create a record of type A with a name equal to your LMS hostname (given by ``tutor config printvalue LMS_HOST``) and a value that indicates the IP address of your server. Applications other than the LMS, such as the studio, ecommerce, etc. typically reside in subdomains of the LMS. Thus, you should also create a CNAME record to point all subdomains of the LMS to the LMS_HOST.
-For instance, the demo Open edX server that runs at http://demo.openedx.overhang.io has the following DNS records::
+For instance, to run an Open edX server at https://learn.mydomain.com on a server with IP address 1.1.1.1, you would need to configure the following DNS records::
- demo.openedx 1800 IN A 172.105.89.208
- *.demo.openedx 1800 IN CNAME demo.openedx.overhang.io.
+ learn 1800 IN A 1.1.1.1
+ *.learn 1800 IN CNAME learn.mydomain.com.
.. _cloud_install:
Zero-click AWS installation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---------------------------
Tutor can be launched on Amazon Web Services very quickly with the `official Tutor AMI `__. Shell access is not required, as all configuration will happen through the Tutor web user interface. For detailed installation instructions, we recommend watching the following video:
@@ -86,42 +87,105 @@ Tutor can be launched on Amazon Web Services very quickly with the `official Tut
Upgrading
---------
-With Tutor, it is very easy to upgrade to a more recent Open edX or Tutor release. Just install the latest ``tutor`` version (using either methods above) and run the ``quickstart`` command again. If you have :ref:`customised ` your docker images, you will have to re-build them prior to running ``quickstart``.
+To upgrade your Open edX site or benefit from the latest features and bug fixes, you should simply upgrade Tutor. Start by backing up your data and reading the `release notes `_ for the current release.
+
+Next, upgrade the "tutor" package and its dependencies::
+
+ pip install --upgrade "tutor[full]"
+
+Then run the ``launch`` command again. Depending on your deployment target, run one of::
-``quickstart`` should take care of automatically running the upgrade process. If for some reason you need to *manually* upgrade from an Open edX release to the next, you should run ``tutor local upgrade``. For instance, to upgrade from Juniper to Koa, run::
+ tutor local launch # for local installations
+ tutor dev launch # for local development installations
+ tutor k8s launch # for Kubernetes installation
- tutor local upgrade --from=juniper
+Upgrading with custom Docker images
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you run :ref:`customised ` Docker images, you need to rebuild them before running ``launch``::
+
+ tutor config save
+ tutor images build all # specify here the images that you need to build
+ tutor local launch
+
+Upgrading to a new Open edX release
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Major Open edX releases are published twice a year, in June and December, by the Open edX `Build/Test/Release working group `__. When a new Open edX release comes out, Tutor gets a major version bump (see :ref:`versioning`). Such an upgrade typically includes multiple breaking changes. Any upgrade is final because downgrading is not supported. Thus, when upgrading your platform from one major version to the next, it is strongly recommended to do the following:
+
+1. Read the changes listed in the `CHANGELOG.md `__ file. Breaking changes are identified by a "π₯".
+2. Perform a backup (see the :ref:`backup tutorial `). On a local installation, this is typically done with::
+
+ tutor local stop
+ sudo rsync -avr "$(tutor config printroot)"/ /tmp/tutor-backup/
+
+3. If you created custom plugins, make sure that they are compatible with the newer release.
+4. Test the new release in a sandboxed environment.
+5. If you are running edx-platform, or some other repository from a custom branch, then you should rebase (and test) your changes on top of the latest release tag (see :ref:`edx_platform_fork`).
+
+The process for upgrading from one major release to the next works similarly to any other upgrade, with the ``launch`` command (see above). The single difference is that if the ``launch`` command detects that your tutor environment was generated with an older release, it will perform a few release-specific upgrade steps. These extra upgrade steps will be performed just once. But they will be ignored if you updated your local environment (for instance: with ``tutor config save``) before running ``launch``. This situation typically occurs if you need to re-build some Docker images (see above). In such a case, you should make use of the ``upgrade`` command. For instance, to upgrade a local installation from Quince to Redwood and rebuild some Docker images, run::
+
+ tutor config save
+ tutor images build all # list the images that should be rebuilt here
+ tutor local upgrade --from=quince
+ tutor local launch
+
+
+Running older releases of Open edX
+-------------------------------------
+
+Instructions for installing the appropriate Tutor version for older Open edX releases. Each command ensures compatibility between Open edX and its corresponding Tutor version. For more details on versioning conventions in Tutor, see the :ref:`versioning` section.
+
++-------------------+---------------+--------------------------------------------+
+| Open edX Release | Tutor version | Installation command |
++===================+===============+============================================+
+| Juniper | v10 | pip install 'tutor[full]>=10.0.0,<11.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Koa | v11 | pip install 'tutor[full]>=11.0.0,<12.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Lilac | v12 | pip install 'tutor[full]>=12.0.0,<13.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Maple | v13 | pip install 'tutor[full]>=13.0.0,<14.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Nutmeg | v14 | pip install 'tutor[full]>=14.0.0,<15.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Olive | v15 | pip install 'tutor[full]>=15.0.0,<16.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Palm | v16 | pip install 'tutor[full]>=16.0.0,<17.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Quince | v17 | pip install 'tutor[full]>=17.0.0,<18.0.0' |
++-------------------+---------------+--------------------------------------------+
+| Redwood | v18 | pip install 'tutor[full]>=18.0.0,<19.0.0' |
++-------------------+---------------+--------------------------------------------+
.. _autocomplete:
-Autocomplete
-------------
+Shell autocompletion
+--------------------
-Tutor is built on top of `Click `_, which is a great library for building command line interface (CLI) tools. As such, Tutor benefits from all Click features, including `auto-completion `_. After installing Tutor, auto-completion can be enabled by running::
+Tutor is built on top of `Click `_, which is a great library for building command line interface (CLI) tools. As such, Tutor benefits from all Click features, including `auto-completion `_. After installing Tutor, auto-completion can be enabled in bash by running::
- _TUTOR_COMPLETE=source tutor >> ~/.bashrc
+ _TUTOR_COMPLETE=bash_source tutor >> ~/.bashrc
If you are running zsh, run instead::
- _TUTOR_COMPLETE=source_zsh tutor >> ~/.zshrc
+ _TUTOR_COMPLETE=zsh_source tutor >> ~/.zshrc
After opening a new shell, you can test auto-completion by typing::
tutor
-.. include:: podman.rst
-
Uninstallation
--------------
-It is fairly easy to completely uninstall Tutor and to delete the Open edX platforms that is running locally.
+It is fairly easy to completely uninstall Tutor and to delete the Open edX platforms that are running locally.
-First of all, stop any locally-running platform::
+First of all, stop any locally-running platform and remove all Tutor containers::
- tutor local stop
- tutor dev stop
+ tutor local dc down --remove-orphans
+ tutor dev dc down --remove-orphans
-Then, delete all data associated to your Open edX platform::
+Then, delete all data associated with your Open edX platform::
# WARNING: this step is irreversible
sudo rm -rf "$(tutor config printroot)"
@@ -129,7 +193,13 @@ Then, delete all data associated to your Open edX platform::
Finally, uninstall Tutor itself::
# If you installed tutor from source
- pip uninstall tutor-openedx
+ pip uninstall tutor
# If you downloaded the tutor binary
sudo rm /usr/local/bin/tutor
+
+ # Optionally, you may want to remove Tutor plugins installed.
+ # You can get a list of the installed plugins:
+ pip freeze | grep tutor
+ # You can then remove them using the following command:
+ pip uninstall
diff --git a/docs/intro.rst b/docs/intro.rst
index c6b4a23d85..ee96c66439 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -6,7 +6,7 @@ Concepts
What is Open edX?
-----------------
-`Open edX `_ is a thriving open source project, backed by a great community, for running an online learning platform at scale. Open edX comes with an LMS (Learning Management System) where students access course contents, a CMS (Content Management System) that course staff uses to design courses, and a few other components to provide more services to students, course staff and platform administrators.
+`Open edX `_ is a thriving open source project, backed by a great community, for running an online learning platform at scale. Open edX comes with an LMS (Learning Management System) where students access course contents, a CMS (Content Management System) that course staff uses to design courses, and a few other components to provide more services to students, course staff, and platform administrators.
Should I use Open edX?
----------------------
@@ -18,80 +18,120 @@ Open edX competitors include `Moodle `__, `Instructure's Ca
* Multiple extension points for comprehensive customization
* Modern, intuitive user interface to keep students engaged
-Open edX is a safe bet: it is backed by edX.org, a US-based non-profit that is committed to open source and which runs Open edX to service its millions of learners. With Open edX you can be sure that the features you need will be available. If it's good enough for Harvard, the MIT or the French government, then it will probably also work for you.
+Open edX is a safe bet: it is backed by edX.org, a US-based non-profit that is committed to open source and which runs Open edX to service its millions of learners. With Open edX you can be sure that the features you need will be available. If it's good enough for Harvard, the MIT, or the French government, then it will probably also work for you.
Should I self-host Open edX or rely on a hosting provider?
----------------------------------------------------------
Third-party Open edX providers can provide you with custom, closed-source features that they developed internally. However, their pricing is usually per-seat: that makes it difficult to predict how much running Open edX will actually cost you if you don't know in advance how many students will connect to your platform. And once you start scaling up and adding many students, running the platform will become very expensive.
-On the other hand, running Open edX on your own servers will help you keep your costs under control. Because you own your servers and data, you will always be able to migrate your platform, either to a different cloud provider or an Open edX service provider. This is the true power of open source.
+On the other hand, running Open edX on your own servers will help you keep your costs under control. Because you own your servers and data, you will always be able to migrate your platform, either to a different cloud provider or an Open edX service provider. This is the true power of the open source.
Should I use Tutor?
-------------------
-Running software on premises is cheaper only if your management costs don't go through the roof. You do not want to hire a full-time devops team just for managing your online learning platform. This is why we created Tutor: to make it easy to run a state-of-the-art online learning platform without breaking the bank. Historically, it's always been difficult to install Open edX with the native installation scripts. For instance, there are no official instructions for upgrading an existing Open edX platform: the `recommended approach `__ is to backup all data, trash the server and create a new one. As a consequence, people tend not to upgrade their platform and keep running on deprecated releases. Tutor makes it possible even to non-technical users to launch, manage and upgrade Open edX at any scale. Should you choose at some point that Tutor is not the right solution for you, you always have an escape route: because Tutor is open source software, you can easily dump your data and switch to a different installation method. But we are confident you will not do that π
+Running software on-premises is cheaper only if your management costs don't go through the roof. You do not want to hire a full-time devops team just for managing your online learning platform. This is why we created Tutor: to make it easy to run a state-of-the-art online learning platform without breaking the bank. Historically, it's always been difficult to install Open edX with native installation scripts. For instance, there are no official instructions for upgrading an existing Open edX platform: the `recommended approach `__ is to backup all data, trash the server, and create a new one. As a consequence, people tend not to upgrade their platform and keep running on deprecated releases. Tutor makes it possible even for non-technical users to launch, manage and upgrade Open edX at any scale. Should you choose at some point that Tutor is not the right solution for you, you always have an escape route: because Tutor is open source software, you can easily dump your data and switch to a different installation method. But we are confident you will not do that π
To learn more about Tutor, watch this 7-minute lightning talk that was made at the 2019 Open edX conference in San Diego, CA (with `slides `_):
.. youtube:: Oqc7c-3qFc4
-How does Tutor work, technically speaking?
-------------------------------------------
+How does Tutor simplify Open edX deployment?
+--------------------------------------------
Tutor simplifies the deployment of Open edX by:
1. Separating the configuration logic from the deployment platforms.
2. Running application processes in cleanly separated `docker containers `_.
3. Providing user-friendly, reliable commands for common administration tasks, including upgrades and monitoring.
-4. Using a simple :ref:`plugin system ` that makes it easy to extend and customize Open edX.
+4. Using a simple :ref:`plugin system ` that makes it easy to extend and customise Open edX.
.. image:: https://overhang.io/static/img/openedx-plus-docker-is-tutor.png
:alt: Open edX + Docker = Tutor
:width: 500px
:align: center
-Because Docker containers are becoming an industry-wide standard, that means that with Tutor it becomes possible to run Open edX anywhere: for now, Tutor supports deploying on a local server, with `docker-compose `_, and in a large cluster, with `Kubernetes `_. But in the future, Tutor may support other deployment platforms.
+Because Docker containers are becoming an industry-wide standard, that means that with Tutor it becomes possible to run Open edX anywhere: for now, Tutor supports deploying on a local server, with `docker compose `_, and in a large cluster, with `Kubernetes `_. But in the future, Tutor may support other deployment platforms.
Where can I try Open edX and Tutor?
-----------------------------------
-A demo Open edX platform is available at https://demo.openedx.overhang.io. This platform was deployed using Tutor and the `Indigo theme `__. Feel free to play around with the following credentials:
+A sandbox Open edX platform is available at https://sandbox.openedx.edly.io. This platform was deployed using Tutor and the `Indigo theme `__. Feel free to play around with the following credentials:
* Admin user: username=admin email=admin@overhang.io password=admin
* Student user: username=student email=student@overhang.io password=student
-The Android mobile application for this website can be downloaded at this url: http://demo.openedx.overhang.io/static/mobile/app.apk
+The Android mobile application for this demo platform can be downloaded at this url: https://mobile.sandbox.openedx.edly.io/app.apk
Urls:
-* LMS: https://demo.openedx.overhang.io
-* Analytics (from the `Figures plugin `__): https://demo.openedx.overhang.io/figures
-* Studio (CMS): https://studio.demo.openedx.overhang.io
+* LMS: https://sandbox.openedx.edly.io
+* Studio (CMS): https://studio.sandbox.openedx.edly.io
The platform is reset every day at 9:00 AM, `Paris (France) time `__, so feel free to try and break things as much as you want.
+.. _how_does_tutor_work:
+
How does Tutor work?
--------------------
+Tutor is a piece of software that takes care of exactly three things:
+
+1. Project configuration: user-specific settings (such as secrets) are stored in a single ``config.yml`` file.
+2. Template rendering: all the files that are necessary to run your platform are generated from a set of templates and user-specific settings.
+3. Command-line interface (CLI): frequently-used administration commands are gathered in a convenient, unified CLI.
+
You can experiment with Tutor very quickly: start by `installing `_ Tutor. Then run::
- tutor config save --interactive
+ $ tutor config save --interactive
+
+Then, to view the result of the above command::
+
+ $ cd "$(tutor config printroot)"
+ $ ls
+ config.yml env
+
+The ``config.yml`` file contains your user-specific Open edX settings (item #1 above). The ``env/`` folder contains the rendered templates which will be used to run your Open edX platform (item #2). For instance, the ``env/local`` folder contains the ``docker-compose.yml`` file to run Open edX locally.
+
+The values from ``config.yml`` are used to generate the environment files in ``env/``. As a consequence, **every time the values from** ``config.yml`` **are modified, the environment must be regenerated** with ``tutor config save``..
+
+Because the Tutor environment is generated entirely from the values in ``config.yml``, you can ``rm -rf`` the ``env/`` folder at any time and re-create it with ``tutor config save``. Another consequence is that **any manual change made to a file in** ``env/`` **will be overwritten by** ``tutor config save`` **commands**. Consider yourself warned!
+
+You can now take advantage of the Tutor-powered CLI (item #3) to bootstrap your Open edX platform::
+
+ tutor local launch
+
+Under the hood, Tutor simply runs ``docker compose`` and ``docker`` commands to launch your platform. These commands are printed in the standard output, such that you are free to replicate the same behaviour by simply copying/pasting the same commands.
+
+How do I navigate Tutor's command-line interface?
+-------------------------------------------------
+
+Tutor commands are structured in an easy-to-follow hierarchy. At the top level, there are command trees for image and configuration management::
+
+ tutor config ...
+ tutor images ...
+
+as well as command trees for each mode in which Tutor can run::
+
+ tutor local ... # Commands for managing a local Open edX deployment.
+ tutor k8s ... # Commands for managing a Kubernetes Open edX deployment.
+ tutor dev ... # Commands for hacking on Open edX in development mode.
+
+Within each mode, Tutor has subcommands for managing that type of Open edX instance. Many of them are common between modes, such as ``launch``, ``start``, ``stop``, ``exec``, and ``logs``. For example::
-This command does two things:
+ tutor local logs # View logs of a local deployment.
+ tutor k8s logs # View logs of a Kubernetes-managed deployment.
+ tutor dev logs # View logs of a development platform.
-1. Generate a ``config.yml`` configuration file: this file contains core :ref:`configuration parameters ` for your Open edX platforms, such as passwords and feature flags.
-2. Generate an ``env/`` folder, which we call the Tutor "environment", and which contains all the files that are necessary to run an Open edX platform: these are mostly Open edX configuration files.
+Many commands can be further parameterized to specify their target and options, for example::
-All these files are stored in a single folder, called the Tutor project root. On Linux, this folder is in ``~/.local/share/tutor``. On Mac OS it is ``~/Library/Application Support/tutor``.
+ tutor local logs cms # View logs of the CMS container in a local deployment.
+ tutor k8s logs mysql # View logs of MySQL in Kubernetes-managed deployment.
+ tutor dev logs lms --tail 10 # View ten lines of logs of the LMS container in development mode.
-The values from ``config.yml`` are used to generate the environment files in ``env/``. As a consequence, **every time the values from** ``config.yml`` **are modified, the environment must be regenerated**. This can be done with::
-
- tutor config save
-
-Another consequence is that **any manual change made to a file in** ``env/`` **will be overwritten by** ``tutor config save`` **commands**. Consider yourself warned!
+And that's it! You do not need to understand Tutor's entire command-line interface to get started. Using the ``--help`` option that's available on every command, it is easy to learn as you go. For an in-depth guide, you can also explore the `CLI Reference `_.
I'm ready, where do I start?
----------------------------
-Right :ref:`here `!
\ No newline at end of file
+Right :ref:`here `!
diff --git a/docs/k8s.rst b/docs/k8s.rst
index 087d93da40..ee57ea6154 100644
--- a/docs/k8s.rst
+++ b/docs/k8s.rst
@@ -20,24 +20,36 @@ Tutor was tested with server version 1.14.1 and client 1.14.3.
Memory
~~~~~~
-In the following, we assume you have access to a working Kubernetes cluster. `kubectl` should use your cluster configuration by default. To launch a cluster locally, you may try out Minikube. Just follow the `official installation instructions `_.
+In the following, we assume you have access to a working Kubernetes cluster. ``kubectl`` should use your cluster configuration by default. To launch a cluster locally, you may try out Minikube. Just follow the `official installation instructions `__.
-The Kubernetes cluster should have at least 4Gb of RAM on each node. When running Minikube, the virtual machine should have that much allocated memory. See below for an example with VirtualBox:
+The Kubernetes cluster should have at least 4Gb of RAM on each node. When running Minikube, the virtual machine should have that much-allocated memory. See below for an example with VirtualBox:
.. image:: img/virtualbox-minikube-system.png
:alt: Virtualbox memory settings for Minikube
-Ingress controller and SSL/TLS certificates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Load Balancer and SSL/TLS certificates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-As of Tutor v11, it is no longer required to setup an Ingress controller to access your platform. Instead Caddy exposes a LoadBalancer service and SSL/TLS certificates are transparently generated at runtime.
+By default, Tutor deploys a `LoadBalancer `__ service that exposes the Caddy deployment to the outside world. As in the local installation, this service is responsible for transparently generating SSL/TLS certificates at runtime. You will need to point your DNS records to this LoadBalancer object before the platform can work correctly. Thus, you should first start the Caddy load balancer, with::
-S3-like object storage with `MinIO `_
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ tutor k8s start caddy
-Like many web applications, Open edX needs to persist data. In particular, it needs to persist files uploaded by students and course designers. In the local installation, these files are persisted to disk, on the host filesystem. But on Kubernetes, it is difficult to share a single filesystem between different pods. This would require persistent volume claims with `ReadWriteMany` access mode, and these are difficult to setup.
+Get the external IP of this service::
-Luckily, there is another solution: at `edx.org `_, uploaded files are persisted on AWS S3: Open edX is compatible out-of-the-box with the S3 API for storing user-generated files. The problem with S3 is that it introduces a dependency on AWS. To solve this problem, Tutor comes with a plugin that emulates the S3 API but stores files on premises. This is achieved thanks to `MinIO `_. If you want to deploy a production platform to Kubernetes, you will most certainly need to enable the ``minio`` plugin::
+ kubectl --namespace openedx get services/caddy
+
+Use this external IP to configure your DNS records. Once the DNS records are configured, you should verify that the Caddy container has properly generated the SSL/TLS certificates by checking the container logs::
+
+ tutor k8s logs -f caddy
+
+If for some reason, you would like to deploy your own load balancer, you should set ``ENABLE_WEB_PROXY=false`` just like in the :ref:`local installation `. Then, point your load balancer at the "caddy" service, which will be a `ClusterIP `__.
+
+S3-like object storage with `MinIO `__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Like many web applications, Open edX needs to persist data. In particular, it needs to persist files uploaded by students and course designers. In the local installation, these files are persisted to disk, on the host filesystem. But on Kubernetes, it is difficult to share a single filesystem between different pods. This would require persistent volume claims with `ReadWriteMany` access mode, and these are difficult to set up.
+
+Luckily, there is another solution: at `edx.org `_, uploaded files are persisted on AWS S3: Open edX is compatible out-of-the-box with the S3 API for storing user-generated files. The problem with S3 is that it introduces a dependency on AWS. To solve this problem, Tutor comes with a plugin that emulates the S3 API but stores files on-premises. This is achieved thanks to `MinIO `__. If you want to deploy a production platform to Kubernetes, you will most certainly need to enable the ``minio`` plugin::
tutor plugins enable minio
@@ -46,18 +58,22 @@ The "minio.LMS_HOST" domain name will have to point to your Kubernetes cluster.
Kubernetes dashboard
~~~~~~~~~~~~~~~~~~~~
-This is not a requirement per se, but it's very convenient to have a visual interface of the Kubernetes cluster. We suggest the official `Kubernetes dashboard `_. Depending on your Kubernetes provider, you may need to install a dashboard yourself. There are generic instructions on the `project's README `_. AWS provides `specific instructions `_.
+This is not a requirement per se, but it's very convenient to have a visual interface of the Kubernetes cluster. We suggest the official `Kubernetes dashboard `__. Depending on your Kubernetes provider, you may need to install a dashboard yourself. There are general instructions on the `project's README `__. AWS provides `specific instructions `__.
On Minikube, the dashboard is already installed. To access the dashboard, run::
minikube dashboard
+Lastly, Tutor itself provides a rudimentary listing of your cluster's nodes, workloads, and services::
+
+ tutor k8s status
+
Technical details
-----------------
-Under the hood, Tutor wraps ``kubectl`` commands to interact with the cluster. The various commands called by Tutor are printed in the console, so that you can reproduce and modify them yourself.
+Under the hood, Tutor wraps ``kubectl`` commands to interact with the cluster. The various commands called by Tutor are printed in the console so that you can reproduce and modify them yourself.
-Basically, the whole platform is described in manifest files stored in ``$(tutor config printroot)/env/k8s``. There is also a ``kustomization.yml`` file at the project root for `declarative application management `_. This allows us to start and update resources with commands similar to ``kubectl apply -k $(tutor config printroot) --selector=...`` (see the ``kubectl apply`` `official documentation `_).
+Basically, the whole platform is described in manifest files stored in ``$(tutor config printroot)/env/k8s``. There is also a ``kustomization.yml`` file at the project root for `declarative application management `__. This allows us to start and update resources with commands similar to ``kubectl apply -k $(tutor config printroot) --selector=...`` (see the ``kubectl apply`` `official documentation `__).
The other benefit of ``kubectl apply`` is that it allows you to customise the Kubernetes resources as much as you want. For instance, the default Tutor configuration can be extended by a ``kustomization.yml`` file stored in ``$(tutor config printroot)/env-custom/`` and which would start with::
@@ -67,21 +83,21 @@ The other benefit of ``kubectl apply`` is that it allows you to customise the Ku
- ../env/
...
-To learn more about "kustomizations", refer to the `official documentation `__.
+To learn more about "kustomizations", refer to the `official documentation `__.
Quickstart
----------
Launch the platform on Kubernetes in one command::
- tutor k8s quickstart
+ tutor k8s launch
-All Kubernetes resources are associated to the "openedx" namespace. If you don't see anything in the Kubernetes dashboard, you are probably looking at the wrong namespace... π
+All Kubernetes resources are associated with the "openedx" namespace. If you don't see anything in the Kubernetes dashboard, you are probably looking at the wrong namespace... π
.. image:: img/k8s-dashboard.png
:alt: Kubernetes dashboard ("openedx" namespace)
-The same ``tutor k8s quickstart`` command can be used to upgrade the cluster to the latest version.
+The same ``tutor k8s launch`` command can be used to upgrade the cluster to the latest version.
Other commands
--------------
@@ -90,15 +106,40 @@ As with the :ref:`local installation `, there are multiple commands to ru
tutor k8s -h
-In particular, the `tutor k8s start` command restarts and reconfigures all services by running ``kubectl apply``. That means that you can delete containers, deployments or just any other kind of resources, and Tutor will re-create them automatically. You should just beware of not deleting any persistent data stored in persistent volume claims. For instance, to restart from a "blank slate", run::
+In particular, the ``tutor k8s start`` command restarts and reconfigures all services by running ``kubectl apply``. That means that you can delete containers, deployments, or just any other kind of resources, and Tutor will re-create them automatically. You should just beware of not deleting any persistent data stored in persistent volume claims. For instance, to restart from a "blank slate", run::
tutor k8s stop
tutor k8s start
All non-persisting data will be deleted, and then re-created.
-Guides
-------
+Common tasks
+------------
+
+Using `tutor k8s apply` with Dry Run
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``tutor k8s apply`` command acts as a wrapper around ``kubectl apply``, facilitating the application of Kubernetes resource configurations stored in ``$(tutor config printroot)/env/k8s``. To apply the configurations, execute the following command::
+
+ tutor k8s apply
+
+Before making any changes, it is possible to validate the configurations without modifications by using the ``dry-run`` option along with server-side validation. The command is as follows::
+
+ tutor k8s apply --dry-run=server --validate=true
+
+- ``--dry-run=server``: This option simulates the application of configurations on the server-side, providing insights into how Kubernetes would interpret the changes.
+- ``--validate=true``: This option validates the manifests against Kubernetes API standards, which aids in catching potential errors prior to application.
+
+Utilizing the dry-run feature ensures a more robust deployment process for the Open edX platform on Kubernetes.
+
+Executing commands inside service pods
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Tutor and plugin documentation usually often instructions to execute some ``tutor local run ...`` commands. These commands are only valid when running Tutor locally with docker compose, and will not work on Kubernetes. Instead, you should run ``tutor k8s exec ...`` commands. Arguments and options should be identical.
+
+For instance, to run a Python shell in the lms container, run::
+
+ tutor k8s exec lms ./manage.py lms shell
Running a custom "openedx" Docker image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -112,8 +153,33 @@ Some Tutor plugins and customization procedures require that the "openedx" image
Updating docker images
~~~~~~~~~~~~~~~~~~~~~~
-Kubernetes does not provide a single command for updating docker images out of the box. A `commonly used trick `_ is to modify an innocuous label on all resources::
+Kubernetes does not provide a single command for updating docker images out of the box. A `commonly used trick `__ is to modify an innocuous label on all resources::
kubectl patch -k "$(tutor config printroot)/env" --patch "{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"`date +'%Y%m%d-%H%M%S'`\"}}}}}"
+.. _customizing_kubernetes_sources:
+
+Customizing Kubernetes resources
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Plugins can customize any Kubernetes resource in Tutor by overriding the definition of the resource with a :patch:`k8s-override` patch. For example, to change the volume size for MongoDB from ``5Gi`` to ``10Gi``, add the following to the plugin:
+
+::
+
+ # myplugin/tutormyplugin/patches/k8s-override
+
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: mongodb
+ labels:
+ app.kubernetes.io/component: volume
+ app.kubernetes.io/name: mongodb
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+
diff --git a/docs/local.rst b/docs/local.rst
index eccc391909..7f3ebcb307 100644
--- a/docs/local.rst
+++ b/docs/local.rst
@@ -5,6 +5,11 @@ Local deployment
This method is for deploying Open edX locally on a single server, where docker images are orchestrated with `docker-compose `_.
+.. note::
+ As of v16.0.0, Tutor now uses the ``docker compose`` subcommand instead of the separate ``docker-compose`` command.
+
+.. _tutor_root:
+
In the following, environment and data files will be generated in a user-specific project folder which will be referred to as the "**project root**". On Linux, the default project root is ``~/.local/share/tutor``. An alternative project root can be defined by passing the ``--root=...`` option to the ``tutor`` command, or defining the ``TUTOR_ROOT=...`` environment variable::
tutor --root=/path/to/tutorroot run ...
@@ -12,24 +17,21 @@ In the following, environment and data files will be generated in a user-specifi
export TUTOR_ROOT=/path/to/tutorroot
tutor run ...
-.. note::
- As of v10.0.0, a locally-running Open edX platform can no longer be accessed from http://localhost or http://studio.localhost. Instead, when running ``tutor local quickstart``, you must now decide whether you are running a platform that will be used in production. If not, the platform will be automatically be bound to http://local.overhang.io and http://studio.local.overhang.io, which are domain names that point to 127.0.0.1 (localhost). This change was made to facilitate internal communication between Docker containers.
-
Main commands
-------------
All available commands can be listed by running::
- tutor local help
+ tutor local --help
All-in-one command
~~~~~~~~~~~~~~~~~~
A fully-functional platform can be configured and run in one command::
- tutor local quickstart
+ tutor local launch
-But you may want to run commands one at a time: it's faster when you need to run only part of the local deployment process, and it helps you understand how your platform works. In the following we decompose the ``quickstart`` command.
+But you may want to run commands one at a time: it's faster when you need to run only part of the local deployment process, and it helps you understand how your platform works. In the following, we decompose the ``launch`` command.
Configuration
~~~~~~~~~~~~~
@@ -38,7 +40,7 @@ Configuration
tutor config save --interactive
-This is the only non-automatic step in the installation process. You will be asked various questions about your Open edX platform and appropriate configuration files will be generated. If you would like to automate this step then you should run ``tutor config save --interactive`` once. After that, there will be a ``config.yml`` file at the root of the project folder: this file contains all the configuration values for your platform, such as randomly generated passwords, domain names, etc.
+This is the only non-automatic step in the installation process. You will be asked various questions about your Open edX platform and appropriate configuration files will be generated. If you would like to automate this step then you should run ``tutor config save --interactive`` once. This will generate a ``config.yml`` file in the **project root**. This file contains all the configuration values for your platform, such as randomly generated passwords, domain names, etc. The location of the **project root** can be found by running ``tutor config printroot``. See :ref:`section above `.
If you want to run a fully automated installation, upload the ``config.yml`` file to wherever you want to run Open edX. You can then entirely skip the configuration step.
@@ -75,7 +77,7 @@ Service initialisation
::
- tutor local init
+ tutor local do init
This command should be run just once. It will initialise all applications in a running platform. In particular, this will create the required databases tables and apply database migrations for all applications.
@@ -96,9 +98,17 @@ Finally, tracking logs that store `user events `_, run::
+After a fresh installation, your platform will not have a single course. To import the `Open edX demo course `_, run::
- tutor local importdemocourse
+ tutor local do importdemocourse
.. _settheme:
@@ -127,9 +137,7 @@ Setting a new theme
The default Open edX theme is rather bland, so Tutor makes it easy to switch to a different theme::
- tutor local settheme mytheme $(tutor config printvalue LMS_HOST) $(tutor config printvalue CMS_HOST)
-
-Notice that we pass the hostnames of the LMS and the CMS to the ``settheme`` command: this is because in Open edX, themes are assigned per domain name.
+ tutor local do settheme mytheme
Out of the box, only the default "open-edx" theme is available. We also developed `Indigo, a beautiful, customizable theme `__ which is easy to install with Tutor.
@@ -152,138 +160,14 @@ After modifying Open edX settings, for instance when running ``tutor config save
tutor local exec lms reload-uwsgi
-.. _portainer:
-
-Docker container web UI with `Portainer `__
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Portainer is a web UI for managing docker containers. It lets you view your entire Open edX platform at a glace. Try it! It's really cool::
-
- docker run --rm \
- --volume=/var/run/docker.sock:/var/run/docker.sock \
- --volume=/tmp/portainer:/data \
- -p 9000:9000 \
- portainer/portainer:latest --bind=:9000
-
-.. .. image:: https://portainer.io/images/screenshots/portainer.gif
- ..:alt: Portainer demo
-
-You can then view the portainer UI at `http://localhost:9000 `_. You will be asked to define a password for the admin user. Then, select a "Local environment" to work on; hit "Connect" and select the "local" group to view all running containers.
-
-Among many other things, you'll be able to view the logs for each container, which is really useful.
-
-Guides
-------
-
-.. _web_proxy:
-
-Running Open edX behind a web proxy
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The containerized web server ([Caddy](caddyserver.com/)) needs to listen to ports 80 and 443 on the host. If there is already a webserver running on the host, such as Apache or Nginx, the caddy container will not be able to start. Tutor supports running behind a web proxy. To do so, add the following configuration::
-
- tutor config save --set RUN_CADDY=false --set NGINX_HTTP_PORT=81
-
-In this example, the nginx container port would be mapped to 81 instead of 80. You must then configure the web proxy on the host. As of v11.0.0, configuration files are no longer provided for automatic configuration of your web proxy. Basically, you should setup a reverse proxy to `localhost:NGINX_HTTP_PORT` from the following hosts: LMS_HOST, preview.LMS_HOST, CMS_HOST, as well as any additional host exposed by your plugins.
-
-.. warning::
- In this setup, the Nginx HTTP port will be exposed to the world. Make sure to configure your server firewall to block unwanted connections to your server's `NGINX_HTTP_PORT`. Alternatively, you can configure the Nginx container to accept only local connections::
-
- tutor config save --set NGINX_HTTP_PORT=127.0.0.1:81
-
-Running multiple Open edX platforms on a single server
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-With Tutor, it is easy to run multiple Open edX instances on a single server. To do so, the following configuration parameters must be different for all platforms:
-
-- ``TUTOR_ROOT``: so that configuration, environment and data are not mixed up between platforms.
-- ``LOCAL_PROJECT_NAME``: the various docker-compose projects cannot share the same name.
-- ``NGINX_HTTP_PORT``: ports cannot be shared by two different containers.
-- ``LMS_HOST``, ``CMS_HOST``: the different platforms must be accessible from different domain (or subdomain) names.
-
-In addition, a web proxy must be setup on the host, as described :ref:`above `.
-
-As an example, here is how to launch two different platforms, with nginx running as a web proxy::
-
- # platform 1
- export TUTOR_ROOT=~/openedx/site1
- tutor config save --interactive --set RUN_CADDY=false --set LOCAL_PROJECT_NAME=tutor_site1 --set NGINX_HTTP_PORT=81
- tutor local quickstart
- sudo ln -s "$(tutor config printroot)/env/local/proxy/nginx/openedx.conf" /etc/nginx/sites-enabled/site1.conf
-
- # platform 2
- export TUTOR_ROOT=~/openedx/site2
- tutor config save --interactive --set RUN_CADDY=false --set LOCAL_PROJECT_NAME=tutor_site2 --set NGINX_HTTP_PORT=82
- tutor local quickstart
- sudo ln -s "$(tutor config printroot)/env/local/proxy/nginx/openedx.conf" /etc/nginx/sites-enabled/site2.conf
-
-You should then have two different platforms, completely isolated from one another, running on the same server.
-
-Loading different production settings for ``edx-platform``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The default settings module loaded by ``edx-platform`` is ``tutor.production``. The folders ``$(tutor config printroot)/env/apps/openedx/settings/lms`` and ``$(tutor config printroot)/env/apps/openedx/settings/cms`` are mounted as ``edx-platform/lms/envs/tutor`` and ``edx-platform/cms/envs/tutor`` inside the docker containers. Thus, to use your own settings, you must do two things:
-
-1. Copy your settings files for the lms and the cms to ``$(tutor config printroot)/env/apps/openedx/settings/lms/mysettings.py`` and ``$(tutor config printroot)/env/apps/openedx/settings/cms/mysettings.py``.
-2. Load your settings by adding ``EDX_PLATFORM_SETTINGS=tutor.mysettings`` to ``$(tutor config printroot)/env/local/.env``.
-
-Of course, your settings should be compatible with the docker installation. You can get some inspiration from the ``production.py`` settings modules generated by Tutor, or just import it as a base by adding ``from .production import *`` at the top of ``mysettings.py``.
-
-Upgrading from earlier versions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Upgrading from v3+
-******************
-
-Just upgrade Tutor using your :ref:`favorite installation method ` and run quickstart again::
-
- tutor local quickstart
-
-Upgrading from v1 or v2
-***********************
-
-Versions 1 and 2 of Tutor were organized differently: they relied on many different ``Makefile`` and ``make`` commands instead of a single ``tutor`` executable. To migrate from an earlier version, you should first stop your platform::
-
- make stop
-
-Then, install Tutor using one of the :ref:`installation methods `. Then, create the Tutor project root and move your data::
-
- mkdir -p "$(tutor config printroot)"
- mv config.json data/ "$(tutor config printroot)"
-
-Finally, launch your platform with::
-
- tutor local quickstart
-
-Backups/Migrating to a different server
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-With Tutor, all data are stored in a single folder. This means that it's extremely easy to migrate an existing platform to a different server. For instance, it's possible to configure a platform locally on a laptop, and then move this platform to a production server.
-
-1. Make sure `tutor` is installed on both servers with the same version.
-2. Stop any running platform on server 1::
-
- tutor local stop
-
-3. Transfer the configuration, environment and platform data from server 1 to server 2::
-
- rsync -avr "$(tutor config printroot)/" username@server2:/tmp/tutor/
-
-4. On server 2, move the data to the right location::
-
- mv /tmp/tutor "$(tutor config printroot)"
-
-5. Start the instance with::
- tutor local start -d
+Customizing the deployed services
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Making database dumps
-~~~~~~~~~~~~~~~~~~~~~
+You might want to customise the docker-compose services listed in ``$(tutor config printroot)/env/local/docker-compose.yml``. To do so, you should create a ``docker-compose.override.yml`` file in that same folder::
-To dump all data from the MySQL and Mongodb databases used on the platform, run the following commands::
+ vim $(tutor config printroot)/env/local/docker-compose.override.yml
- tutor local exec -e MYSQL_ROOT_PASSWORD="$(tutor config printvalue MYSQL_ROOT_PASSWORD)" mysql \
- sh -c 'mysqldump --all-databases --password=$MYSQL_ROOT_PASSWORD > /var/lib/mysql/dump.sql'
- tutor local exec mongodb mongodump --out=/data/db/dump.mongodb
+The values in this file will override the values from ``docker-compose.yml`` and ``docker-compose.prod.yml``, as explained in the `docker-compose documentation `__.
-The ``dump.sql`` and ``dump.mongodb`` files will be located in ``$(tutor config printroot)/data/mysql`` and ``$(tutor config printroot)/data/mongodb``.
+Similarly, the job service configuration can be overridden by creating a ``docker-compose.jobs.override.yml`` file in that same folder.
diff --git a/docs/plugins.rst b/docs/plugins.rst
deleted file mode 100644
index c6c55e1d68..0000000000
--- a/docs/plugins.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-.. _plugins:
-
-Plugins
-=======
-
-Tutor comes with a plugin system that allows anyone to customise the deployment of an Open edX platform very easily. The vision behind this plugin system is that users should not have to fork the Tutor repository to customise their deployments. For instance, if you have created a new application that integrates with Open edX, you should not have to describe how to manually patch the platform settings, ``urls.py`` or ``*.env.json`` files. Instead, you can create a "tutor-myapp" plugin for Tutor. Then, users will start using your application in three simple steps::
-
- # 1) Install the plugin
- pip install tutor-myapp
- # 2) Enable the plugin
- tutor plugins enable myapp
- # 3) Reconfigure and restart the platform
- tutor local quickstart
-
-For simple changes, it may be extremely easy to create a Tutor plugin: even non-technical users may get started with :ref:`simple yaml plugins `.
-
-In the following we learn how to use and create Tutor plugins.
-
-Commands
---------
-
-List installed plugins::
-
- tutor plugins list
-
-Enable/disable a plugin::
-
- tutor plugins enable myplugin
- tutor plugins disable myplugin
-
-After enabling or disabling a plugin, the environment should be re-generated with::
-
- tutor config save
-
-.. _existing_plugins:
-
-Existing plugins
-----------------
-
-- `Course discovery `__: Deploy an API for interacting with your course catalog
-- `Ecommerce `__: Sell courses and products on your Open edX platform
-- `Figures `__: Visualize daily stats about course engagement
-- `MinIO `__: S3 emulator for object storage and scalable Open edX deployment.
-- `Notes `__: Allows students to annotate portions of the courseware.
-- `Xqueue `__: for external grading
-
-Plugin development
-------------------
-
-.. toctree::
- :maxdepth: 2
-
- plugins/api
- plugins/gettingstarted
- plugins/examples
\ No newline at end of file
diff --git a/docs/plugins/examples.rst b/docs/plugins/examples.rst
index beab509450..2b1d763d7f 100644
--- a/docs/plugins/examples.rst
+++ b/docs/plugins/examples.rst
@@ -1,62 +1,92 @@
.. _plugins_examples:
-Examples of Tutor plugins
-=========================
+========
+Examples
+========
The following are simple examples of :ref:`Tutor plugins ` that can be used to modify the behaviour of Open edX.
Skip email validation for new users
------------------------------------
+===================================
::
- name: skipemailvalidation
- version: 0.1.0
- patches:
- common-env-features: |
- "SKIP_EMAIL_VALIDATION": true
+ from tutor import hooks
+
+ hooks.Filters.ENV_PATCHES.add_item(
+ (
+ "common-env-features",
+ """
+ "SKIP_EMAIL_VALIDATION": true
+ """
+ )
+ )
Enable bulk enrollment view in the LMS
---------------------------------------
+======================================
::
- name: enablebulkenrollmentview
- version: 0.1.0
- patches:
- lms-env-features: |
- "ENABLE_BULK_ENROLLMENT_VIEW": true
+ from tutor import hooks
+
+ hooks.Filters.ENV_PATCHES.add_item(
+ (
+ "lms-env-features",
+ """
+ "ENABLE_BULK_ENROLLMENT_VIEW": true
+ """
+ )
+ )
Enable Google Analytics
------------------------
+=======================
::
- name: googleanalytics
- version: 0.1.0
- patches:
- openedx-common-settings: |
- # googleanalytics special settings
- GOOGLE_ANALYTICS_ACCOUNT = "UA-your-account"
- GOOGLE_ANALYTICS_TRACKING_ID = "UA-your-tracking-id"
+ from tutor import hooks
-Enable SAML authentication
---------------------------
+ hooks.Filters.ENV_PATCHES.add_items([
+ (
+ "openedx-common-settings",
+ "GOOGLE_ANALYTICS_4_ID = 'MY-MEASUREMENT-ID'"
+ ),
+ (
+ "mfe-lms-common-settings",
+ "MFE_CONFIG['GOOGLE_ANALYTICS_4_ID'] = 'MY-MEASUREMENT-ID'"
+ ),
+ ])
-::
+.. note::
+ Please be aware that as of May 2023 Google Analytics support has been upgraded from Google Universal Analytics to Google Analytics 4 and you may need to update your configuration as mentioned in the `Open edX docs `__.
- name: saml
- version: 0.1.0
- patches:
- common-env-features: |
- "ENABLE_THIRD_PARTY_AUTH" : true
- openedx-lms-common-settings: |
- # saml special settings
- THIRD_PARTY_AUTH_BACKENDS = "third_party_auth.saml.SAMLAuthBackend"
- openedx-auth: |
- "SOCIAL_AUTH_SAML_SP_PRIVATE_KEY": "yoursecretkey",
- "SOCIAL_AUTH_SAML_SP_PUBLIC_CERT": "yourpubliccert"
+Enable SAML authentication
+==========================
+
+::
+
+ from tutor import hooks
+
+ hooks.Filters.ENV_PATCHES.add_items([
+ (
+ "common-env-features",
+ '"ENABLE_THIRD_PARTY_AUTH": true',
+ ),
+ (
+ "openedx-lms-common-settings",
+ """
+ # saml special settings
+ AUTHENTICATION_BACKENDS += ["common.djangoapps.third_party_auth.saml.SAMLAuthBackend", "django.contrib.auth.backends.ModelBackend"]
+ """
+ ),
+ (
+ "openedx-auth",
+ """
+ "SOCIAL_AUTH_SAML_SP_PRIVATE_KEY": "yoursecretkey",
+ "SOCIAL_AUTH_SAML_SP_PUBLIC_CERT": "yourpubliccert"
+ """
+ ),
+ ])
Do not forget to replace "yoursecretkey" and "yourpubliccert" with your own values.
diff --git a/docs/plugins/index.rst b/docs/plugins/index.rst
new file mode 100644
index 0000000000..399f9568bc
--- /dev/null
+++ b/docs/plugins/index.rst
@@ -0,0 +1,11 @@
+
+=======
+Plugins
+=======
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ examples
+ v0/index
diff --git a/docs/plugins/intro.rst b/docs/plugins/intro.rst
new file mode 100644
index 0000000000..890125ca6b
--- /dev/null
+++ b/docs/plugins/intro.rst
@@ -0,0 +1,63 @@
+.. _plugins:
+
+============
+Introduction
+============
+
+Tutor comes with a plugin system that allows anyone to customise the deployment of an Open edX platform very easily. The vision behind this plugin system is that users should not have to fork the Tutor repository to customise their deployments. For instance, if you have created a new application that integrates with Open edX, you should not have to describe how to manually patch the platform settings, ``urls.py`` or ``*.env.yml`` files. Instead, you can create a "tutor-myapp" plugin for Tutor. This plugin will be in charge of making changes to the platform settings. Then, users will be able to use your application in three simple steps::
+
+ # 1) Install the plugin
+ pip install tutor-myapp
+ # 2) Enable the plugin
+ tutor plugins enable myapp
+ # 3) Reconfigure and restart the platform
+ tutor local launch
+
+For simple changes, it may be extremely easy to create a Tutor plugin: even non-technical users may get started with our :ref:`plugin_development_tutorial` tutorial. We also provide a list of :ref:`simple example plugins `.
+
+To learn about the different ways in which plugins can extend Tutor, check out the :ref:`hooks catalog `.
+
+Plugin commands cheatsheet
+==========================
+
+List installed plugins::
+
+ tutor plugins list
+
+Enable/disable a plugin::
+
+ tutor plugins enable myplugin
+ tutor plugins disable myplugin
+
+The full plugins CLI is described in the :ref:`reference documentation `.
+
+.. _existing_plugins:
+
+Existing plugins
+================
+
+Many plugins are available from plugin indexes. These indexes are lists of plugins, similar to the `pypi `__ or `npm `__ indexes. By default, Tutor comes with the "main" plugin index. You can check available plugins from this index by running::
+
+ tutor plugins update
+ tutor plugins search
+
+More plugins can be downloaded from the "contrib" index::
+
+ tutor plugins index add contrib
+ tutor plugins search
+
+The "main" and "contrib" indexes include a curated list of plugins that are well maintained and introduce useful features to Open edX. These indexes are maintained by `Edly `__. For more information about these indexes, refer to the official `overhangio/tpi `__ repository.
+
+Thanks to these indexes, it is very easy to download and upgrade plugins. For instance, to install the `notes plugin `__::
+
+ tutor plugins install notes
+
+Upgrade all your plugins with::
+
+ tutor plugins upgrade all
+
+To list indexes that you are downloading plugins from, run::
+
+ tutor plugins index list
+
+For more information about these indexes, check the `official Tutor plugin indexes (TPI) `__ repository.
diff --git a/docs/plugins/api.rst b/docs/plugins/v0/api.rst
similarity index 60%
rename from docs/plugins/api.rst
rename to docs/plugins/v0/api.rst
index 9ffd3e533e..37c01eea8d 100644
--- a/docs/plugins/api.rst
+++ b/docs/plugins/v0/api.rst
@@ -1,20 +1,28 @@
Plugin API
==========
-Plugins can affect the behaviour of Tutor at multiple levels. First, plugins can define new services with their Docker images, settings and the right initialisation commands. To do so you will have to define custom :ref:`config `, :ref:`patches `, :ref:`hooks ` and :ref:`templates `. Then, plugins can also extend the CLI by defining their own :ref:`commands `.
+.. include:: legacy.rst
-.. _plugin_config:
+Plugins can affect the behaviour of Tutor at multiple levels. They can:
+
+* Add new settings or modify existing ones in the Tutor configuration (see :ref:`config `).
+* Add new templates to the Tutor project environment or modify existing ones (see :ref:`patches `, :ref:`templates ` and :ref:`hooks `).
+* Add custom commands to the Tutor CLI (see :ref:`command `).
+
+There exist two different APIs to create Tutor plugins: either with YAML files or Python packages. YAML files are more simple to create but are limited to just configuration and template patches.
+
+.. _v0_plugin_config:
config
~~~~~~
The ``config`` attribute is used to modify existing and add new configuration parameters:
-* ``config["add"]`` are key/values that should be added to the user-specific ``config.yml`` configuration. Add there passwords, secret keys and other values that do not have a default value.
-* ``config["defaults"]`` are default key/values for this plugin. These values will not be added to the ``config.yml`` user file unless users override them manually with ``tutor config save --set ...``.
-* ``config["set"]`` are existing key/values that should be modified. Be very careful what you add there! Plugins may define conflicting values for some parameters.
+* ``config["add"]`` are key/values that should be added to the user-specific ``config.yml`` configuration. Add there the passwords, secret keys, and other values that do not have a reasonable default value for all users.
+* ``config["defaults"]`` are default key/values for this plugin. These values can be accessed even though they are not added to the ``config.yml`` user file. Users can override them manually with ``tutor config save --set ...``.
+* ``config["set"]`` are existing key/values that should be modified. Be very careful what you add there! Different plugins may define conflicting values for some parameters.
- "set" and "default" key names will be automatically prefixed with the plugin name, in upper case.
+ "add" and "defaults" key names will be automatically prefixed with the plugin name, in upper case.
Example::
@@ -36,22 +44,15 @@ This configuration from the "myplugin" plugin will set the following values:
- ``MYPLUGIN_DOCKER_IMAGE``: this value will by default not be stored in ``config.yml``, but ``tutor config printvalue MYPLUGIN_DOCKER_IMAGE`` will print ``username/imagename:latest``.
- ``MASTER_PASSWORD`` will be set to ``h4cked``. Needless to say, plugin developers should avoid doing this.
-.. _plugin_patches:
+.. _v0_plugin_patches:
patches
~~~~~~~
-Plugin patches affect the rendered environment templates. In many places the Tutor templates include calls to ``{{ patch("patchname") }}``. This grants plugin developers the possibility to modify the content of rendered templates. Plugins can add content in these places by adding values to the ``patches`` attribute.
+Plugin patches affect the rendered environment templates. In many places the Tutor templates include calls to ``{{ patch("patchname") }}``. This grants plugin developers the possibility to modify the content of rendered templates. Plugins can add content in these places by adding values to the ``patches`` attribute. See :ref:`patches` for the complete list available patches.
-.. note::
- The list of existing patches can be found by searching for `{{ patch(` strings in the Tutor source code::
-
- git grep "{{ patch"
-
- The list of patches can also be browsed online `on Github `__.
-
Example::
-
+
patches = {
"local-docker-compose-services": """redis:
image: redis:latest"""
@@ -60,10 +61,11 @@ Example::
This will add a Redis instance to the services run with ``tutor local`` commands.
.. note::
- The ``patches`` attribute can be a callable function instead of a static dict value.
+ In Python plugins, remember that ``patches`` can be a callable function instead of a static dict value.
+ One can use this to dynamically load a list of patch files from a folder.
-.. _plugin_hooks:
+.. _v0_plugin_hooks:
hooks
~~~~~
@@ -76,16 +78,16 @@ Hooks are actions that are run during the lifetime of the platform. For instance
The services that will be run during initialisation should be added to the ``init`` hook, for instance for database creation and migrations.
Example::
-
+
hooks = {
"init": ["myservice1", "myservice2"]
}
-
+
During initialisation, "myservice1" and "myservice2" will be run in sequence with the commands defined in the templates ``myplugin/hooks/myservice1/init`` and ``myplugin/hooks/myservice2/init``.
-To initialise a "foo" service, Tutor runs the "foo-job" service that is found in the ``env/local/docker-compose.jobs.yml`` file. By default, Tutor comes with a few services in this file: mysql-job, lms-job, cms-job, forum-job. If your plugin requires running custom services during initialisation, you will need to add them to the ``docker-compose.jobs.yml`` template. To do so, just use the "local-docker-compose-jobs-services" patch.
+To initialise a "foo" service, Tutor runs the "foo-job" service that is found in the ``env/local/docker-compose.jobs.yml`` file. By default, Tutor comes with a few services in this file: mysql-job, lms-job, cms-job. If your plugin requires running custom services during initialisation, you will need to add them to the ``docker-compose.jobs.yml`` template. To do so, just use the "local-docker-compose-jobs-services" patch.
-In Kubernetes, the approach is the same, except that jobs are implemented as actual job objects in the ``k8s/jobs.yml`` template. To add your own services there, your plugin should implement the "k8s-jobs" patch.
+In Kubernetes, the approach is the same, except that jobs are implemented as actual job objects in the ``k8s/jobs.yml`` template. To add your services there, your plugin should implement the "k8s-jobs" patch.
``pre-init``
++++++++++++
@@ -102,13 +104,13 @@ Example::
hooks = {
"build-image": {"myimage": "myimage:latest"}
}
-
+
With this hook, users will be able to build the ``myimage:latest`` docker image by running::
-
+
tutor images build myimage
or::
-
+
tutor images build all
This assumes that there is a ``Dockerfile`` file in the ``myplugin/build/myimage`` subfolder of the plugin templates directory.
@@ -119,43 +121,47 @@ This assumes that there is a ``Dockerfile`` file in the ``myplugin/build/myimage
This hook allows pulling/pushing images from/to a docker registry.
Example::
-
+
hooks = {
"remote-image": {"myimage": "myimage:latest"},
}
With this hook, users will be able to pull and push the ``myimage:latest`` docker image by running::
-
+
tutor images pull myimage
tutor images push myimage
or::
-
+
tutor images pull all
tutor images push all
-.. _plugin_templates:
+.. _v0_plugin_templates:
templates
~~~~~~~~~
-In order to define plugin-specific hooks, a plugin should also have a template directory that includes the plugin hooks. The ``templates`` attribute should point to that directory.
+To define plugin-specific hooks, a plugin should also have a template directory that includes the plugin hooks. The ``templates`` attribute should point to that directory.
Example::
-
+
import os
templates = os.path.join(os.path.abspath(os.path.dirname(__file__)), "templates")
With the above declaration, you can store plugin-specific templates in the ``templates/myplugin`` folder next to the ``plugin.py`` file.
-In Tutor, templates are `Jinja2 `__-formatted files that will be rendered in the Tutor environment (the ``$(tutor config printroot)/env`` folder) when running ``tutor config save``. The environment files are overwritten every time the environment is saved. Plugin developers can create templates that make use of the built-in `Jinja2 API `__. In addition, a couple additional filters are added by Tutor:
-
+In Tutor, templates are `Jinja2 `__-formatted files that will be rendered in the Tutor environment (the ``$(tutor config printroot)/env`` folder) when running ``tutor config save``. The environment files are overwritten every time the environment is saved. Plugin developers can create templates that make use of the built-in `Jinja2 API `__. In addition, a couple of additional filters are added by Tutor:
+
* ``common_domain``: Return the longest common name between two domain names. Example: ``{{ "studio.demo.myopenedx.com"|common_domain("lms.demo.myopenedx.com") }}`` is equal to "demo.myopenedx.com".
* ``encrypt``: Encrypt an arbitrary string. The encryption process is compatible with `htpasswd `__ verification.
* ``list_if``: In a list of ``(value, condition)`` tuples, return the list of ``value`` for which the ``condition`` is true.
-* ``patch``: See :ref:`patches `.
+* ``long_to_base64``: Base-64 encode a long integer.
+* ``iter_values_named``: Yield the values of the configuration settings that match a certain pattern. Example: ``{% for value in iter_values_named(prefix="KEY", suffix="SUFFIX")%}...{% endfor %}``. By default, only non-empty values are yielded. To iterate also on empty values, pass the ``allow_empty=True`` argument.
+* ``patch``: See :ref:`patches `.
* ``random_string``: Return a random string of the given length composed of ASCII letters and digits. Example: ``{{ 8|random_string }}``.
* ``reverse_host``: Reverse a domain name (see `reference `__). Example: ``{{ "demo.myopenedx.com"|reverse_host }}`` is equal to "com.myopenedx.demo".
+* ``rsa_import_key``: Import a PEM-formatted RSA key and return the corresponding object.
+* ``rsa_private_key``: Export an RSA private key in PEM format.
* ``walk_templates``: Iterate recursively over the templates of the given folder. For instance::
{% for file in "apps/myplugin"|walk_templates %}
@@ -167,41 +173,61 @@ When saving the environment, template files that are stored in a template root w
* Binary files with the following extensions: .ico, .jpg, .png, .ttf
* Files that are stored in a folder named "partials", or one of its subfolders.
-.. _plugin_command:
+.. _v0_plugin_command:
command
~~~~~~~
-A plugin can provide custom command line commands. Commands are assumed to be `click.Command `__ objects.
+Python plugins can provide a custom command line interface.
+The ``command`` attribute is assumed to be a `click.Command `__ object,
+and you typically implement them using the `click.command `__ decorator.
+
+You may also use the `click.pass_obj `__ decorator to pass the CLI `context `__, such as when you want to access Tutor configuration settings from your command.
Example::
-
+
import click
-
+ from tutor import config as tutor_config
+
@click.command(help="I'm a plugin command")
- def command():
+ @click.pass_obj
+ def command(context):
+ config = tutor_config.load(context.root)
+ lms_host = config["LMS_HOST"]
click.echo("Hello from myplugin!")
+ click.echo(f"My LMS host is {lms_host}")
Any user who installs the ``myplugin`` plugin can then run::
-
+
$ tutor myplugin
Hello from myplugin!
+ My LMS host is learn.myserver.com
+
+You can even define subcommands by creating `command groups `__::
-You can even define subcommands by creating `command groups `__::
-
import click
-
+
@click.group(help="I'm a plugin command group")
def command():
pass
-
- @click.command(help="I'm a plugin subcommand")
+
+ @command.command(help="I'm a plugin subcommand")
def dosomething():
click.echo("This subcommand is awesome")
-This would allow any user to run::
+This would allow any user to see your sub-commands::
+
+ $ tutor myplugin
+ Usage: tutor myplugin [OPTIONS] COMMAND [ARGS]...
+
+ I'm a plugin command group
+
+ Commands:
+ dosomething I'm a plugin subcommand
+
+and then run them::
$ tutor myplugin dosomething
This subcommand is awesome
-
-See the official `click documentation `__ for more information.
+
+See the official `click documentation `__ for more information.
diff --git a/docs/plugins/gettingstarted.rst b/docs/plugins/v0/gettingstarted.rst
similarity index 71%
rename from docs/plugins/gettingstarted.rst
rename to docs/plugins/v0/gettingstarted.rst
index 6421a898bb..1f597e1946 100644
--- a/docs/plugins/gettingstarted.rst
+++ b/docs/plugins/v0/gettingstarted.rst
@@ -1,6 +1,8 @@
Getting started with plugin development
=======================================
+.. include:: legacy.rst
+
Plugins can be created in two different ways: either as plain YAML files or installable Python packages. YAML files are great when you need to make minor changes to the default platform, such as modifying settings. For creating more complex applications, it is recommended to create python packages.
.. _plugins_yaml:
@@ -9,15 +11,15 @@ YAML file
~~~~~~~~~
YAML files that are stored in the tutor plugins root folder will be automatically considered as plugins. The location of the plugin root can be found by running::
-
+
tutor plugins printroot
On Linux, this points to ``~/.local/share/tutor-plugins``. The location of the plugin root folder can be modified by setting the ``TUTOR_PLUGINS_ROOT`` environment variable.
-YAML plugins need to define two extra keys: "name" and "version". Custom CLI commands are not supported by YAML plugins.
+YAML plugins must define two special top-level keys: ``name`` and ``version``. Then, YAML plugins may use two more top-level keys to customise Tutor's behaviour: ``config`` and ``patches``. Custom CLI commands, templates, and hooks are not supported by YAML plugins.
Let's create a simple plugin that adds your own `Google Analytics `__ tracking code to your Open edX platform. We need to add the ``GOOGLE_ANALYTICS_ACCOUNT`` and ``GOOGLE_ANALYTICS_TRACKING_ID`` settings to both the LMS and the CMS settings. To do so, we will only have to create the ``openedx-common-settings`` patch, which is shared by the development and the production settings both for the LMS and the CMS. First, create the plugin directory::
-
+
mkdir "$(tutor plugins printroot)"
Then add the following content to the plugin file located at ``$(tutor plugins printroot)/myplugin.yml``::
@@ -31,44 +33,57 @@ Then add the following content to the plugin file located at ``$(tutor plugins p
GOOGLE_ANALYTICS_TRACKING_ID = "UA-654321-1"
Of course, you should replace your Google Analytics tracking code with your own. You can verify that your plugin is correctly installed, but not enabled yet::
-
+
$ tutor plugins list
googleanalytics@0.1.0 (disabled)
-
+
You can then enable your newly-created plugin::
-
- tutor plugins enable googleanalytics
-Update your environment to apply changes from your plugin::
-
- tutor config save
+ tutor plugins enable googleanalytics
You should be able to view your changes in every LMS and CMS settings file::
grep -r googleanalytics "$(tutor config printroot)/env/apps/openedx/settings/"
Now just restart your platform to start sending tracking events to Google Analytics::
-
- tutor local quickstart
+
+ tutor local launch
That's it! And it's very easy to share your plugins. Just upload them to your Github repo and share the url with other users. They will be able to install your plugin by running::
-
+
tutor plugins install https://raw.githubusercontent.com/username/yourrepo/master/googleanalytics.yml
Python package
~~~~~~~~~~~~~~
-Creating a plugin as a Python package allows you to define more complex logic and to store your patches in a more structured way. Python Tutor plugins are regular Python packages that define a specific entrypoint: ``tutor.plugin.v0``.
+Creating a plugin as a Python package allows you to define more complex logic and store your patches in a more structured way. Python Tutor plugins are regular Python packages that define an entry point within the ``tutor.plugin.v0`` group:
Example::
-
+
from setuptools import setup
setup(
...
- entry_points={"tutor.plugin.v0": ["myplugin = myplugin.plugin"]},
+ entry_points={
+ "tutor.plugin.v0": ["myplugin = myplugin.plugin"]
+ },
)
-The ``myplugin.plugin`` python module should then declare the ``config``, ``hooks``, etc. attributes that will define its behaviour.
+The ``myplugin/plugin.py`` Python module can then define the attributes ``config``, ``patches``, ``hooks``, and ``templates`` to specify the plugin's behaviour. The attributes may be defined either as dictionaries or as zero-argument callables returning dictionaries; in the latter case, the callable will be evaluated upon plugin load. Finally, the ``command`` attribute can be defined as an instance of ``click.Command`` to define the plugin's command line interface.
+
+Example::
+
+ import click
+
+ templates = pkg_resources.resource_filename(...)
+ config = {...}
+ hooks = {...}
+
+ def patches():
+ ...
+
+ @click.command(...)
+ def command():
+ ...
To get started on the right foot, it is strongly recommended to create your first plugin with the `tutor plugin cookiecutter `__::
diff --git a/docs/plugins/v0/index.rst b/docs/plugins/v0/index.rst
new file mode 100644
index 0000000000..72bcff9bcf
--- /dev/null
+++ b/docs/plugins/v0/index.rst
@@ -0,0 +1,11 @@
+=============
+Legacy v0 API
+=============
+
+.. include:: legacy.rst
+
+.. toctree::
+ :maxdepth: 2
+
+ api
+ gettingstarted
diff --git a/docs/plugins/v0/legacy.rst b/docs/plugins/v0/legacy.rst
new file mode 100644
index 0000000000..c68fee46db
--- /dev/null
+++ b/docs/plugins/v0/legacy.rst
@@ -0,0 +1 @@
+.. warning:: The v0 plugin API is no longer the recommended way of developing new plugins for Tutor, starting from Tutor v13.2.0. See our :ref:`plugin creation tutorial ` to learn more about the v1 plugin API. Existing v0 plugins will remain supported for some time but developers are encouraged to start migrating their plugins as soon as possible to make use of the new API. Please read the `upgrade instructions `__ to upgrade v0 plugins generated with the v0 plugin cookiecutter.
diff --git a/docs/podman.rst b/docs/podman.rst
deleted file mode 100644
index 353475f42a..0000000000
--- a/docs/podman.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-Running Tutor with Podman
--------------------------
-
-You have the option of running Tutor with `Podman `__, instead of the native Docker tools. This has some practical advantages: it does not require a running Docker daemon, and it enables you to run and build Docker images without depending on any system component running ``root``. As such, it is particularly useful for building Tutor images from CI pipelines.
-
-The ``podman`` CLI aims to be fully compatible with the ``docker`` CLI, and ``podman-compose`` is meant to be a fully-compatible alias of ``docker-compose``. This means that you should be able to use together with Tutor, without making any changes to Tutor itself.
-
-.. warning::
- Since this was written, it was discovered that there are major compatibility issues between ``podman-compose`` and ``docker-compose``. Thus, podman cannot be considered a drop-in replacement of Docker in the context of Tutor -- at least for running Open edX locally.
-
-.. warning::
- You should not attempt to run Tutor with Podman on a system that already has native ``docker`` installed. If you want to switch to ``podman`` using the aliases described here, you should uninstall (or at least stop) the native Docker daemon first.
-
-
-Enabling Podman
-~~~~~~~~~~~~~~~
-
-Podman is supported on a variety of development platforms, see the `installation instructions `_ for details.
-
-Once you have installed Podman and its dependencies on the platform of your choice, you'll need to make sure that its ``podman`` binary, usually installed as ``/usr/bin/podman``, is aliased to ``docker``, and is included as such in your system ``$PATH``. On some CentOS and Fedora releases you can install a package named ``podman-docker`` to do this for you, but on other platforms you'll need to take of this yourself.
-
-- If ``$HOME/bin`` is in your ``$PATH``, you can create a symbolic link there::
-
- ln -s $(which podman) $HOME/bin/docker
-
-- If you want to instead make ``docker`` a system-wide alias for ``podman``, you can create your symlink in ``/usr/local/bin``, an action that normally requires ``root`` privileges::
-
- sudo ln -s $(which podman) /usr/local/bin/docker
-
-
-Enabling podman-compose
-~~~~~~~~~~~~~~~~~~~~~~~
-
-``podman-compose`` is available as a package from PyPI, and can thus be installed with ``pip``. See `its README `_ for installation instructions. Note that if you have installed Tutor in its own virtualenv, you'll need to run ``pip install podman-compose`` in that same virtualenv.
-
-Once installed, you'll again need to create a symbolic link that aliases ``docker-compose`` to ``podman-compose``.
-
-- If you run Tutor and ``podman-compose`` in a virtualenv, create the symlink in that virtualenv's ``bin`` directory: activate the virtualenv, then run::
-
- ln -s $(which podman-compose) $(dirname $(which podman-compose))/docker-compose
-
-- If you do not, create the symlink in ``/usr/local/bin``, using ``root`` privileges::
-
- sudo ln -s $(which podman-compose) /usr/local/bin/docker-compose
-
-
-Verifying your environment
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Once you have configured your symbolic links as described, you should be able to run ``docker version`` and ``docker-compose --help`` and their output should agree, respectively, with ``podman version`` and ``podman-compose --help``.
-
-After that, you should be able to use ``tutor local``, ``tutor build``, and other commands as if you had installed the native Docker tools.
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 7d20341aad..0c774f8b4a 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -3,23 +3,27 @@
Quickstart (1-click install)
----------------------------
-1. `Download `_ the latest stable release of Tutor and place the ``tutor`` executable in your path. From the command line:
+1. Install the latest stable release of Tutor from pip:
-.. include:: cli_download.rst
+.. include:: download/pip.rst
-2. Run ``tutor local quickstart``
+Or `download `_ the pre-compiled binary and place the ``tutor`` executable in your path:
+
+.. include:: download/binary.rst
+
+2. Run ``tutor local launch``
3. You're done!
**That's it?**
-Yes :) This is what happens when you run ``tutor local quickstart``:
+Yes :) This is what happens when you run ``tutor local launch``:
1. You answer a few questions about the :ref:`configuration` of your Open edX platform.
2. Configuration files are generated from templates.
3. Docker images are downloaded.
4. Docker containers are provisioned.
-5. A full, production-ready Open edX platform (`Koa `__ release) is run with docker-compose.
+5. A full, production-ready Open edX platform (`Redwood `__ release) is run with docker-compose.
-The whole procedure should require less than 10 minutes, on a server with a good bandwidth. Note that your host environment will not be affected in any way, since everything runs inside docker containers. Root access is not even necessary.
+The whole procedure should require less than 10 minutes, on a server with good bandwidth. Note that your host environment will not be affected in any way, since everything runs inside docker containers. Root access is not even necessary.
-There's a lot more to Tutor than that! To learn more about what you can do with Tutor and Open edX, check out the :ref:`whatnext` section. If the quickstart installation method above somehow didn't work for you, check out the :ref:`troubleshooting` guide.
\ No newline at end of file
+There's a lot more to Tutor than that! To learn more about what you can do with Tutor and Open edX, check out the :ref:`whatnext` section. If the launch installation method above somehow didn't work for you, check out the :ref:`troubleshooting` guide.
diff --git a/docs/reference/api/hooks/actions.rst b/docs/reference/api/hooks/actions.rst
new file mode 100644
index 0000000000..bf73ddbd4d
--- /dev/null
+++ b/docs/reference/api/hooks/actions.rst
@@ -0,0 +1,14 @@
+.. _actions:
+
+=======
+Actions
+=======
+
+Actions are one of the two types of hooks (the other being :ref:`filters`) that can be used to extend Tutor. Each action represents an event that can occur during the application life cycle. Each action has a name, and callback functions can be attached to it. When an action is triggered, these callback functions are called in sequence. Each callback function can trigger side effects, independently from one another.
+
+.. autoclass:: tutor.core.hooks.Action
+ :members:
+
+.. The following are only to ensure that the docs build without warnings
+.. class:: tutor.core.hooks.actions.T
+.. class:: tutor.types.Config
diff --git a/docs/reference/api/hooks/catalog.rst b/docs/reference/api/hooks/catalog.rst
new file mode 100644
index 0000000000..cddd3c63b3
--- /dev/null
+++ b/docs/reference/api/hooks/catalog.rst
@@ -0,0 +1,18 @@
+.. _hooks_catalog:
+
+=============
+Hooks catalog
+=============
+
+Tutor can be extended by making use of "hooks". Hooks are either "actions" or "filters". Here, we list all instances of actions and filters that are used across Tutor. Plugin developers can leverage these hooks to modify the behaviour of Tutor.
+
+The underlying Python hook classes and API are documented :ref:`here `.
+
+.. autoclass:: tutor.hooks.Actions
+ :members:
+
+.. autoclass:: tutor.hooks.Filters
+ :members:
+
+.. autoclass:: tutor.hooks.Contexts
+ :members:
diff --git a/docs/reference/api/hooks/contexts.rst b/docs/reference/api/hooks/contexts.rst
new file mode 100644
index 0000000000..808de983d3
--- /dev/null
+++ b/docs/reference/api/hooks/contexts.rst
@@ -0,0 +1,10 @@
+.. _contexts:
+
+========
+Contexts
+========
+
+Contexts are a feature of the hook-based extension system in Tutor, which allows us to keep track of which components of the code created which callbacks. Contexts are very much an internal concept that most plugin developers should not have to worry about.
+
+.. autoclass:: tutor.core.hooks.Context
+.. autofunction:: tutor.core.hooks.contexts::enter
diff --git a/docs/reference/api/hooks/filters.rst b/docs/reference/api/hooks/filters.rst
new file mode 100644
index 0000000000..81ec443374
--- /dev/null
+++ b/docs/reference/api/hooks/filters.rst
@@ -0,0 +1,15 @@
+.. _filters:
+
+=======
+Filters
+=======
+
+Filters are one of the two types of hooks (the other being :ref:`actions`) that can be used to extend Tutor. Filters allow one to modify the application behavior by transforming data. Each filter has a name, and callback functions can be attached to it. When a filter is applied, these callback functions are called in sequence; the result of each callback function is passed as the first argument to the next callback function. The result of the final callback function is returned to the application as the filter's output.
+
+.. autoclass:: tutor.core.hooks.Filter
+ :members:
+
+.. The following are only to ensure that the docs build without warnings
+.. class:: tutor.core.hooks.filters.T1
+.. class:: tutor.core.hooks.filters.T2
+.. class:: tutor.core.hooks.filters.L
diff --git a/docs/reference/api/hooks/index.rst b/docs/reference/api/hooks/index.rst
new file mode 100644
index 0000000000..f6f130ebb2
--- /dev/null
+++ b/docs/reference/api/hooks/index.rst
@@ -0,0 +1,32 @@
+.. _hooks_api:
+
+=========
+Hooks API
+=========
+
+Types
+=====
+
+This is the Python documentation of the two types of hooks (actions and filters) as well as the contexts system which is used to instrument them. Understanding how Tutor hooks work is useful to create plugins that modify the behaviour of Tutor. However, plugin developers should almost certainly not import these hook types directly. Instead, use the reference :ref:`hooks catalog `.
+
+.. toctree::
+ :maxdepth: 1
+
+ actions
+ filters
+ contexts
+
+Utilities
+=========
+
+Functions
+---------
+
+.. autofunction:: tutor.core.hooks::clear_all
+.. autofunction:: tutor.hooks::lru_cache
+
+Priorities
+----------
+
+.. automodule:: tutor.core.hooks.priorities
+ :members: HIGH, DEFAULT, LOW
diff --git a/docs/reference/cli/config.rst b/docs/reference/cli/config.rst
new file mode 100644
index 0000000000..d97b2f1d10
--- /dev/null
+++ b/docs/reference/cli/config.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.config:config_command
+ :prog: tutor config
+ :nested: full
diff --git a/docs/reference/cli/dev.rst b/docs/reference/cli/dev.rst
new file mode 100644
index 0000000000..a72b495112
--- /dev/null
+++ b/docs/reference/cli/dev.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.dev:dev
+ :prog: tutor dev
+ :nested: full
diff --git a/docs/reference/cli/images.rst b/docs/reference/cli/images.rst
new file mode 100644
index 0000000000..7966bae1b2
--- /dev/null
+++ b/docs/reference/cli/images.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.images:images_command
+ :prog: tutor images
+ :nested: full
diff --git a/docs/reference/cli/index.rst b/docs/reference/cli/index.rst
new file mode 100644
index 0000000000..6995faf8f1
--- /dev/null
+++ b/docs/reference/cli/index.rst
@@ -0,0 +1,13 @@
+Command line interface (CLI)
+============================
+
+.. toctree::
+ :maxdepth: 2
+
+ tutor
+ config
+ dev
+ images
+ k8s
+ local
+ plugins
diff --git a/docs/reference/cli/k8s.rst b/docs/reference/cli/k8s.rst
new file mode 100644
index 0000000000..9334459124
--- /dev/null
+++ b/docs/reference/cli/k8s.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.k8s:k8s
+ :prog: tutor k8s
+ :nested: full
diff --git a/docs/reference/cli/local.rst b/docs/reference/cli/local.rst
new file mode 100644
index 0000000000..91294d6af2
--- /dev/null
+++ b/docs/reference/cli/local.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.local:local
+ :prog: tutor local
+ :nested: full
diff --git a/docs/reference/cli/plugins.rst b/docs/reference/cli/plugins.rst
new file mode 100644
index 0000000000..7bf378e71a
--- /dev/null
+++ b/docs/reference/cli/plugins.rst
@@ -0,0 +1,5 @@
+.. _cli_plugins:
+
+.. click:: tutor.commands.plugins:plugins_command
+ :prog: tutor plugins
+ :nested: full
diff --git a/docs/reference/cli/tutor.rst b/docs/reference/cli/tutor.rst
new file mode 100644
index 0000000000..233bec5841
--- /dev/null
+++ b/docs/reference/cli/tutor.rst
@@ -0,0 +1,3 @@
+.. click:: tutor.commands.cli:cli
+ :prog: tutor
+ :nested: full
diff --git a/docs/reference/index.rst b/docs/reference/index.rst
new file mode 100644
index 0000000000..3281a9cf70
--- /dev/null
+++ b/docs/reference/index.rst
@@ -0,0 +1,11 @@
+Reference
+=========
+
+.. toctree::
+ :maxdepth: 2
+
+ api/hooks/index
+ api/hooks/catalog
+ patches
+ cli/index
+ indexes
diff --git a/docs/reference/indexes.rst b/docs/reference/indexes.rst
new file mode 100644
index 0000000000..45fff4b3c0
--- /dev/null
+++ b/docs/reference/indexes.rst
@@ -0,0 +1,158 @@
+==============
+Plugin indexes
+==============
+
+Plugin indexes are a great way to have your plugins discovered by other users. Plugin indexes make it easy for other Tutor users to install and upgrade plugins from other developers. Examples include the official indexes, which can be found in the `overhangio/tpi `__ repository.
+
+Index file paths
+================
+
+A plugin index is a yaml-formatted file. It can be stored on the web or on your computer. In both cases, the index file location must end with "/plugins.yml". For instance, the following are valid index locations if you run the Open edX "Redwood" release:
+
+- https://overhang.io/tutor/main/redwood/plugins.yml
+- ``/path/to/your/local/index/redwood/plugins.yml``
+
+To add either indexes, run the ``tutor plugins index add`` command without the suffix. For instance::
+
+ tutor plugins index add https://overhang.io/tutor/main
+ tutor plugins index add /path/to/your/local/index/
+
+Your plugin cache should be updated immediately. You can also update the cache at any point by running::
+
+ tutor plugins update
+
+To view current indexes, run::
+
+ tutor plugins index list
+
+To remove an index, run::
+
+ tutor plugins index remove
+
+Plugin entry syntax
+===================
+
+A "plugins.yml" file is a yaml-formatted list of plugin entries. Each plugin entry has two required fields: "name" and "src". For instance, here is a minimal plugin entry::
+
+ - name: mfe
+ src: tutor-mfe
+
+"name" (required)
+-----------------
+
+A plugin name is how it will be referenced when we run ``tutor plugins install `` or ``tutor plugins enable ``. It should be concise and easily identifiable, just like a Python or apt package name.
+
+Plugins with duplicate names will be overridden, depending on the index in which they are declared: indexes further down ``tutor plugins index list`` (which have been added later) will have higher priority.
+
+.. _plugin_index_src:
+
+"src" (required)
+----------------
+
+A plugin source can be either:
+
+1. A pip requirement file format specifier (see `reference `__).
+2. The path to a Python file on your computer.
+3. The URL of a Python file on the web.
+
+In the first case, the plugin will be installed as a Python package. In the other two cases, the plugin will be installed as a single-file plugin.
+
+The following "src" attributes are all valid::
+
+ # Pypi package
+ src: tutor-mfe
+
+ # Pypi package with version specification
+ src: tutor-mfe>=42.0.0,<43.0.0
+
+ # Python package from a private index
+ src: |
+ --index-url=https://pip.mymirror.org
+ my-plugin>=10.0
+
+ # Remote git repository
+ src: -e git+https://github.com/myusername/tutor-contrib-myplugin@v27.0.0#egg=tutor-contrib-myplugin
+
+ # Local editable package
+ src: -e /path/to/my/plugin
+
+"url" (optional)
+----------------
+
+Link to the plugin project, where users can learn more about it and ask for support.
+
+"author" (optional)
+-------------------
+
+Original author of the plugin. Feel free to include your company name and email address here. For instance: "Leather Face ".
+
+"maintainer" (optional)
+-----------------------
+
+Current maintainer of the plugin. Same format as "author".
+
+"description" (optional)
+------------------------
+
+Multi-line string that should contain extensive information about your plugin. The full description will be displayed with ``tutor plugins show ``. It will also be parsed for a match by ``tutor plugins search ``. Only the first line will be displayed in the output of ``tutor plugins search``. Make sure to keep the first line below 128 characters.
+
+
+Examples
+========
+
+Manage plugins in development
+-----------------------------
+
+Plugin developers and maintainers often want to install local versions of their plugins. They usually achieve this with ``pip install -e /path/to/tutor-plugin``. We can improve that workflow by creating an index for local plugins::
+
+ # Create the plugin index directory
+ mkdir -p ~/localindex/redwood/
+ # Edit the index
+ vim ~/localindex/redwood/plugins.yml
+
+Add the following to the index::
+
+ - name: myplugin1
+ src: -e /path/to/tutor-myplugin1
+ - name: myplugin2
+ src: -e /path/to/tutor-myplugin2
+
+Then add the index::
+
+ tutor plugins index add ~/localindex/
+
+Install the plugins::
+
+ tutor plugins install myplugin1 myplugin2
+
+Re-install all plugins::
+
+ tutor plugins upgrade all
+
+The latter commands will install from the local index, and not from the remote indexes, because indexes that are added last have higher priority when plugins with the same names are found.
+
+Install plugins from a private index
+------------------------------------
+
+Plugin authors might want to share plugins with a limited number of users. This is for instance the case when a plugin is for internal use only.
+
+First, users should have access to the ``plugins.yml`` file. There are different ways to achieve that:
+
+- Make the index public: after all, it's mostly the plugins which are private.
+- Grant access to the index from behind a VPN.
+- Hide the index behing a basic HTTP auth url. The index can then be added with ``tutor plugins index add http://user:password@mycompany.com/index/``.
+- Download the index to disk, and then add it from the local path: ``tutor plugins index add ../path/to/index``.
+
+Second, users should be able to install the plugins that are listed in the index. We recommend that the plugins are uploaded to a pip-compatible self-hosted mirror, such as `devpi `__. Alternatively, packages can be installed from a private Git repository. For instance::
+
+ # Install from private pip index
+ - name: myprivateplugin1
+ src: |
+ --index-url=https://my-pip-index.mycompany.com/
+ tutor-contrib-myprivateplugin
+
+ # Install from private git repository
+ - name: myprivateplugin2
+ src: -e git+https://git.mycompany.com/tutor-contrib-myplugin2.git
+
+Both examples work because the :ref:`"src" ` field supports just any syntax that could also be included in a requirements file installed with ``pip install -r requirements.txt``.
diff --git a/docs/reference/patches.rst b/docs/reference/patches.rst
new file mode 100644
index 0000000000..5ef0aece60
--- /dev/null
+++ b/docs/reference/patches.rst
@@ -0,0 +1,402 @@
+.. _patches:
+
+======================
+Template patch catalog
+======================
+
+This is the list of all patches used across Tutor (outside of any plugin). Alternatively, you can search for patches in Tutor templates by grepping the source code::
+
+ git clone https://github.com/overhangio/tutor
+ cd tutor
+ git grep "{{ patch" -- tutor/templates
+
+Or you can list all available patches with the following command::
+
+ tutor config patches list
+
+See also `this GitHub search `__.
+
+.. patch:: caddyfile
+
+``caddyfile``
+=============
+
+File: ``apps/caddy/Caddyfile``
+
+Add here Caddy directives to redirect traffic from the outside to your service containers. You should make use of the "proxy" snippet that simplifies configuration and automatically configures logging. Also, make sure to use the ``$default_site_port`` environment variable to make sure that your service will be accessible both when HTTPS is enabled or disabled. For instance::
+
+ {{ MYPLUGIN_HOST }}{$default_site_port} {
+ import proxy "myservice:8000"
+ }
+
+See the `Caddy reference documentation `__ for more information.
+
+.. patch:: caddyfile-cms
+
+``caddyfile-cms``
+=================
+
+File: ``apps/caddy/Caddyfile``
+
+.. patch:: caddyfile-global
+
+``caddyfile-global``
+====================
+
+File: ``apps/caddy/Caddyfile``
+
+.. patch:: caddyfile-lms
+
+``caddyfile-lms``
+=================
+
+File: ``apps/caddy/Caddyfile``
+
+.. patch:: caddyfile-proxy
+
+``caddyfile-proxy``
+===========================
+
+File: ``apps/caddy/Caddyfile``
+
+.. patch:: cms-env
+
+``cms-env``
+===========
+
+File: ``apps/openedx/config/cms.env.yml``
+
+.. patch:: cms-env-features
+
+``cms-env-features``
+====================
+
+File: ``apps/openedx/config/cms.env.yml``
+
+.. patch:: common-env-features
+
+``common-env-features``
+=======================
+
+Files: ``apps/openedx/config/cms.env.yml``, ``apps/openedx/config/lms.env.yml``
+
+.. patch:: dev-docker-compose-jobs-services
+
+``dev-docker-compose-jobs-services``
+====================================
+
+File: ``dev/docker-compose.jobs.yml``
+
+.. patch:: k8s-deployments
+
+``k8s-deployments``
+===================
+
+File: ``k8s/deployments.yml``
+
+.. patch:: k8s-jobs
+
+``k8s-jobs``
+============
+
+File: ``k8s/jobs.yml``
+
+.. patch:: k8s-override
+
+``k8s-override``
+================
+
+File: ``k8s/override.yml``
+
+Any Kubernetes resource definition in this patch will override the resource defined by Tutor, provided that their names match. See :ref:`Customizing Kubernetes resources ` for an example.
+
+.. patch:: k8s-services
+
+``k8s-services``
+================
+
+File: ``k8s/services.yml``
+
+.. patch:: k8s-volumes
+
+``k8s-volumes``
+===============
+
+File: ``k8s/volumes.yml``
+
+.. patch:: kustomization
+
+``kustomization``
+=================
+
+File: ``kustomization.yml``
+
+.. patch:: kustomization-commonlabels
+
+``kustomization-commonlabels``
+==============================
+
+File: ``kustomization.yml``
+
+.. patch:: kustomization-configmapgenerator
+
+``kustomization-configmapgenerator``
+====================================
+
+File: ``kustomization.yml``
+
+.. patch:: kustomization-patches-strategic-merge
+
+``kustomization-patches-strategic-merge``
+=========================================
+
+File: ``kustomization.yml``
+
+This can be used to add more Kustomization patches that make use of the `strategic merge mechanism `__.
+
+.. patch:: kustomization-resources
+
+``kustomization-resources``
+===========================
+
+File: ``kustomization.yml``
+
+.. patch:: lms-env
+
+``lms-env``
+===========
+
+File: ``apps/openedx/config/lms.env.yml``
+
+.. patch:: lms-env-features
+
+``lms-env-features``
+====================
+
+File: ``apps/openedx/config/lms.env.yml``
+
+.. patch:: local-docker-compose-caddy-aliases
+
+``local-docker-compose-caddy-aliases``
+======================================
+
+File: ``local/docker-compose.prod.yml``
+
+.. patch:: local-docker-compose-cms-dependencies
+
+``local-docker-compose-cms-dependencies``
+=========================================
+
+File: ``local/docker-compose.yml``
+
+.. patch:: local-docker-compose-dev-services
+
+``local-docker-compose-dev-services``
+=====================================
+
+File: ``dev/docker-compose.yml``
+
+.. patch:: local-docker-compose-jobs-services
+
+``local-docker-compose-jobs-services``
+======================================
+
+File: ``local/docker-compose.jobs.yml``
+
+.. patch:: local-docker-compose-lms-dependencies
+
+``local-docker-compose-lms-dependencies``
+=========================================
+
+File: ``local/docker-compose.yml``
+
+.. patch:: local-docker-compose-permissions-command
+
+``local-docker-compose-permissions-command``
+============================================
+
+File: ``apps/permissions/setowners.sh``
+
+Add commands to this script to set ownership of bind-mounted docker-compose volumes at runtime. See :patch:`local-docker-compose-permissions-volumes`.
+
+
+.. patch:: local-docker-compose-permissions-volumes
+
+``local-docker-compose-permissions-volumes``
+============================================
+
+File: ``local/docker-compose.yml``
+
+Add bind-mounted volumes to this patch to set their owners properly. See :patch:`local-docker-compose-permissions-command`.
+
+.. patch:: local-docker-compose-prod-services
+
+``local-docker-compose-prod-services``
+======================================
+
+File: ``local/docker-compose.prod.yml``
+
+.. patch:: local-docker-compose-services
+
+``local-docker-compose-services``
+=================================
+
+File: ``local/docker-compose.yml``
+
+.. patch:: openedx-auth
+
+``openedx-auth``
+================
+
+File: ``apps/openedx/config/partials/auth.yml``
+
+.. patch:: openedx-cms-common-settings
+
+``openedx-cms-common-settings``
+===============================
+
+File: ``apps/openedx/settings/partials/common_cms.py``
+
+.. patch:: openedx-cms-development-settings
+
+``openedx-cms-development-settings``
+====================================
+
+File: ``apps/openedx/settings/cms/development.py``
+
+.. patch:: openedx-cms-production-settings
+
+``openedx-cms-production-settings``
+===================================
+
+File: ``apps/openedx/settings/cms/production.py``
+
+.. patch:: openedx-common-assets-settings
+
+``openedx-common-assets-settings``
+==================================
+
+File: ``build/openedx/settings/partials/assets.py``
+
+
+.. patch:: openedx-common-i18n-settings
+
+``openedx-common-i18n-settings``
+================================
+
+File: ``build/openedx/settings/partials/i18n.py``
+
+.. patch:: openedx-common-settings
+
+``openedx-common-settings``
+===========================
+
+File: ``apps/openedx/settings/partials/common_all.py``
+
+.. patch:: openedx-dev-dockerfile-post-python-requirements
+
+``openedx-dev-dockerfile-post-python-requirements``
+===================================================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-development-settings
+
+``openedx-development-settings``
+================================
+
+Files: ``apps/openedx/settings/cms/development.py``, ``apps/openedx/settings/lms/development.py``
+
+.. patch:: openedx-dockerfile
+
+``openedx-dockerfile``
+======================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-final
+
+``openedx-dockerfile-final``
+============================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-git-patches-default
+
+``openedx-dockerfile-git-patches-default``
+==========================================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-minimal
+
+``openedx-dockerfile-minimal``
+==============================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-post-git-checkout
+
+``openedx-dockerfile-post-git-checkout``
+========================================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-post-python-requirements
+
+``openedx-dockerfile-post-python-requirements``
+===============================================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-dockerfile-pre-assets
+
+``openedx-dockerfile-pre-assets``
+=================================
+
+File: ``build/openedx/Dockerfile``
+
+.. patch:: openedx-lms-common-settings
+
+``openedx-lms-common-settings``
+===============================
+
+File: ``apps/openedx/settings/partials/common_lms.py``
+
+Python-formatted LMS settings used both in production and development.
+
+.. patch:: openedx-lms-development-settings
+
+``openedx-lms-development-settings``
+====================================
+
+File: ``apps/openedx/settings/lms/development.py``
+
+Python-formatted LMS settings in development. Values defined here override the values from :patch:`openedx-lms-common-settings` or :patch:`openedx-lms-production-settings`.
+
+.. patch:: openedx-lms-production-settings
+
+``openedx-lms-production-settings``
+===================================
+
+File: ``apps/openedx/settings/lms/production.py``
+
+Python-formatted LMS settings in production. Values defined here override the values from :patch:`openedx-lms-common-settings`.
+
+``redis-conf``
+==============
+
+File: ``apps/redis/redis.conf``
+
+Implement this patch to override hard-coded Redis configuration values. See the `Redis configuration reference `__`.
+
+``uwsgi-config``
+================
+
+File: ``apps/openedx/settings/uwsgi.ini``
+
+A .INI formatted file used to extend or override the uWSGI configuration.
+
+Check the uWSGI documentation for more details about the `.INI format `__ and the `list of available options