mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-05-30 04:40:49 +00:00
728ef966dc
- 💥[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_*``. - The ``WEB_PROXY`` setting was removed and ``RUN_CADDY`` was added. - 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 - 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. - 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 - 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.
146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
import os
|
|
import shutil
|
|
import urllib.request
|
|
|
|
import click
|
|
|
|
from .. import config as tutor_config
|
|
from .. import env as tutor_env
|
|
from .. import exceptions
|
|
from .. import fmt
|
|
from .. import plugins
|
|
|
|
|
|
@click.group(
|
|
name="plugins",
|
|
short_help="Manage Tutor plugins",
|
|
help="Manage Tutor plugins to add new features and customize your Open edX platform",
|
|
)
|
|
def plugins_command():
|
|
"""
|
|
All plugin commands should work even if there is no existing config file. This is
|
|
because users might enable plugins prior to configuration or environment generation.
|
|
"""
|
|
|
|
|
|
@click.command(name="list", help="List installed plugins")
|
|
@click.pass_obj
|
|
def list_command(context):
|
|
config = tutor_config.load_user(context.root)
|
|
for plugin in plugins.iter_installed():
|
|
status = "" if plugins.is_enabled(config, plugin.name) else " (disabled)"
|
|
print(
|
|
"{plugin}=={version}{status}".format(
|
|
plugin=plugin.name, status=status, version=plugin.version
|
|
)
|
|
)
|
|
|
|
|
|
@click.command(help="Enable a plugin")
|
|
@click.argument("plugin_names", metavar="plugin", nargs=-1)
|
|
@click.pass_obj
|
|
def enable(context, plugin_names):
|
|
config = tutor_config.load_user(context.root)
|
|
for plugin in plugin_names:
|
|
plugins.enable(config, plugin)
|
|
fmt.echo_info("Plugin {} enabled".format(plugin))
|
|
tutor_config.save_config_file(context.root, config)
|
|
fmt.echo_info(
|
|
"You should now re-generate your environment with `tutor config save`."
|
|
)
|
|
|
|
|
|
@click.command(
|
|
short_help="Disable a plugin",
|
|
help="Disable one or more plugins. Specify 'all' to disable all enabled plugins at once.",
|
|
)
|
|
@click.argument("plugin_names", metavar="plugin", nargs=-1)
|
|
@click.pass_obj
|
|
def disable(context, plugin_names):
|
|
config = tutor_config.load_user(context.root)
|
|
if "all" in plugin_names:
|
|
plugin_names = [plugin.name for plugin in plugins.iter_enabled(config)]
|
|
for plugin_name in plugin_names:
|
|
plugins.disable(config, plugin_name)
|
|
delete_plugin(context.root, plugin_name)
|
|
|
|
tutor_config.save_config_file(context.root, config)
|
|
fmt.echo_info(
|
|
"You should now re-generate your environment with `tutor config save`."
|
|
)
|
|
|
|
|
|
def delete_plugin(root, name):
|
|
plugin_dir = tutor_env.pathjoin(root, "plugins", name)
|
|
if os.path.exists(plugin_dir):
|
|
try:
|
|
shutil.rmtree(plugin_dir)
|
|
except PermissionError as e:
|
|
raise exceptions.TutorError(
|
|
"Could not delete file {} from plugin {} in folder {}".format(
|
|
e.filename, name, plugin_dir
|
|
)
|
|
)
|
|
|
|
|
|
@click.command(
|
|
short_help="Print the location of yaml-based plugins",
|
|
help="""Print the location of yaml-based plugins. This location can be manually
|
|
defined by setting the {} environment variable""".format(
|
|
plugins.DictPlugin.ROOT_ENV_VAR_NAME
|
|
),
|
|
)
|
|
def printroot():
|
|
fmt.echo(plugins.DictPlugin.ROOT)
|
|
|
|
|
|
@click.command(
|
|
short_help="Install a plugin",
|
|
help="""Install a plugin, either from a local YAML file or a remote, web-hosted
|
|
location. The plugin will be installed to {}.""".format(
|
|
plugins.DictPlugin.ROOT_ENV_VAR_NAME
|
|
),
|
|
)
|
|
@click.argument("location")
|
|
def install(location):
|
|
basename = os.path.basename(location)
|
|
if not basename.endswith(".yml"):
|
|
basename += ".yml"
|
|
plugin_path = os.path.join(plugins.DictPlugin.ROOT, basename)
|
|
|
|
if location.startswith("http"):
|
|
# Download file
|
|
response = urllib.request.urlopen(location)
|
|
content = response.read().decode()
|
|
elif os.path.isfile(location):
|
|
# Read file
|
|
with open(location) as f:
|
|
content = f.read()
|
|
else:
|
|
raise exceptions.TutorError("No plugin found at {}".format(location))
|
|
|
|
# Save file
|
|
if not os.path.exists(plugins.DictPlugin.ROOT):
|
|
os.makedirs(plugins.DictPlugin.ROOT)
|
|
with open(plugin_path, "w", newline="\n") as f:
|
|
f.write(content)
|
|
fmt.echo_info("Plugin installed at {}".format(plugin_path))
|
|
|
|
|
|
def add_plugin_commands(command_group):
|
|
"""
|
|
Add commands provided by all plugins to the given command group. Each command is
|
|
added with a name that is equal to the plugin name.
|
|
"""
|
|
for plugin in plugins.iter_installed():
|
|
if isinstance(plugin.command, click.Command):
|
|
plugin.command.name = plugin.name
|
|
command_group.add_command(plugin.command)
|
|
|
|
|
|
plugins_command.add_command(list_command)
|
|
plugins_command.add_command(enable)
|
|
plugins_command.add_command(disable)
|
|
plugins_command.add_command(printroot)
|
|
plugins_command.add_command(install)
|