mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-12-12 14:17:46 +00:00
Run pylint on code base
This commit is contained in:
parent
ce1bb05d8e
commit
207229e16e
11
tutor/cli.py
11
tutor/cli.py
@ -6,9 +6,9 @@ import click_repl
|
|||||||
|
|
||||||
from .__about__ import __version__
|
from .__about__ import __version__
|
||||||
from .android import android
|
from .android import android
|
||||||
from .config import config
|
from .config import config_command
|
||||||
from .dev import dev
|
from .dev import dev
|
||||||
from .images import images
|
from .images import images_command
|
||||||
from .k8s import k8s
|
from .k8s import k8s
|
||||||
from .local import local
|
from .local import local
|
||||||
from .ui import ui
|
from .ui import ui
|
||||||
@ -24,11 +24,13 @@ def main():
|
|||||||
sys.stderr.write(fmt.error("Error: {}\n".format(e.args[0])))
|
sys.stderr.write(fmt.error("Error: {}\n".format(e.args[0])))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@click.group(context_settings={'help_option_names': ['-h', '--help', 'help']})
|
@click.group(context_settings={'help_option_names': ['-h', '--help', 'help']})
|
||||||
@click.version_option(version=__version__)
|
@click.version_option(version=__version__)
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Print this help",
|
help="Print this help",
|
||||||
name="help",
|
name="help",
|
||||||
@ -37,9 +39,10 @@ def print_help():
|
|||||||
with click.Context(cli) as context:
|
with click.Context(cli) as context:
|
||||||
click.echo(cli.get_help(context))
|
click.echo(cli.get_help(context))
|
||||||
|
|
||||||
|
|
||||||
click_repl.register_repl(cli, name="ui")
|
click_repl.register_repl(cli, name="ui")
|
||||||
cli.add_command(images)
|
cli.add_command(images_command, name="images")
|
||||||
cli.add_command(config)
|
cli.add_command(config_command, name="config")
|
||||||
cli.add_command(local)
|
cli.add_command(local)
|
||||||
cli.add_command(dev)
|
cli.add_command(dev)
|
||||||
cli.add_command(android)
|
cli.add_command(android)
|
||||||
|
@ -17,7 +17,7 @@ from .__about__ import __version__
|
|||||||
short_help="Configure Open edX",
|
short_help="Configure Open edX",
|
||||||
help="""Configure Open edX and store configuration values in $TUTOR_ROOT/config.yml"""
|
help="""Configure Open edX and store configuration values in $TUTOR_ROOT/config.yml"""
|
||||||
)
|
)
|
||||||
def config():
|
def config_command():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -33,8 +33,7 @@ def save_command(root, silent1, silent2, set_):
|
|||||||
|
|
||||||
def save(root, silent=False, keyvalues=None):
|
def save(root, silent=False, keyvalues=None):
|
||||||
keyvalues = keyvalues or []
|
keyvalues = keyvalues or []
|
||||||
config = {}
|
config = load_current(root)
|
||||||
load_current(config, root)
|
|
||||||
for k, v in keyvalues:
|
for k, v in keyvalues:
|
||||||
config[k] = v
|
config[k] = v
|
||||||
if not silent:
|
if not silent:
|
||||||
@ -57,8 +56,7 @@ def printroot(root):
|
|||||||
@opts.root
|
@opts.root
|
||||||
@click.argument("key")
|
@click.argument("key")
|
||||||
def printvalue(root, key):
|
def printvalue(root, key):
|
||||||
config = {}
|
config = load_current(root)
|
||||||
load_current(config, root)
|
|
||||||
load_defaults(config)
|
load_defaults(config)
|
||||||
try:
|
try:
|
||||||
print(config[key])
|
print(config[key])
|
||||||
@ -71,8 +69,7 @@ def load(root):
|
|||||||
Load configuration, and generate it interactively if the file does not
|
Load configuration, and generate it interactively if the file does not
|
||||||
exist.
|
exist.
|
||||||
"""
|
"""
|
||||||
config = {}
|
config = load_current(root)
|
||||||
load_current(config, root)
|
|
||||||
|
|
||||||
should_update_env = False
|
should_update_env = False
|
||||||
if not os.path.exists(config_path(root)):
|
if not os.path.exists(config_path(root)):
|
||||||
@ -119,20 +116,22 @@ def pre_upgrade_announcement(root):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def load_current(config, root):
|
def load_current(root):
|
||||||
convert_json2yml(root)
|
convert_json2yml(root)
|
||||||
load_base(config, root)
|
config = {}
|
||||||
|
load_base(config)
|
||||||
load_user(config, root)
|
load_user(config, root)
|
||||||
load_env(config, root)
|
load_env(config)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
def load_base(config, root):
|
def load_base(config):
|
||||||
base = serialize.load(env.read("config-base.yml"))
|
base = serialize.load(env.read("config-base.yml"))
|
||||||
for k, v in base.items():
|
for k, v in base.items():
|
||||||
config[k] = v
|
config[k] = v
|
||||||
|
|
||||||
|
|
||||||
def load_env(config, root):
|
def load_env(config):
|
||||||
base_config = serialize.load(env.read("config-base.yml"))
|
base_config = serialize.load(env.read("config-base.yml"))
|
||||||
default_config = serialize.load(env.read("config-defaults.yml"))
|
default_config = serialize.load(env.read("config-defaults.yml"))
|
||||||
keys = set(list(base_config.keys()) + list(default_config.keys()))
|
keys = set(list(base_config.keys()) + list(default_config.keys()))
|
||||||
@ -272,6 +271,6 @@ def config_path(root):
|
|||||||
return os.path.join(root, "config.yml")
|
return os.path.join(root, "config.yml")
|
||||||
|
|
||||||
|
|
||||||
config.add_command(save_command, name="save")
|
config_command.add_command(save_command, name="save")
|
||||||
config.add_command(printroot)
|
config_command.add_command(printroot)
|
||||||
config.add_command(printvalue)
|
config_command.add_command(printvalue)
|
||||||
|
@ -13,6 +13,7 @@ from . import utils
|
|||||||
def dev():
|
def dev():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Run a command in one of the containers",
|
help="Run a command in one of the containers",
|
||||||
context_settings={"ignore_unknown_options": True},
|
context_settings={"ignore_unknown_options": True},
|
||||||
@ -34,6 +35,7 @@ def run(root, edx_platform_path, edx_platform_settings, service, command, args):
|
|||||||
root, edx_platform_path, edx_platform_settings, port, *run_command
|
root, edx_platform_path, edx_platform_settings, port, *run_command
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Run a development server",
|
help="Run a development server",
|
||||||
)
|
)
|
||||||
@ -48,11 +50,13 @@ def runserver(root, edx_platform_path, edx_platform_settings, service):
|
|||||||
service, "./manage.py", service, "runserver", "0.0.0.0:{}".format(port),
|
service, "./manage.py", service, "runserver", "0.0.0.0:{}".format(port),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Stop a running development platform",)
|
@click.command(help="Stop a running development platform",)
|
||||||
@opts.root
|
@opts.root
|
||||||
def stop(root):
|
def stop(root):
|
||||||
docker_compose(root, "rm", "--stop", "--force")
|
docker_compose(root, "rm", "--stop", "--force")
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Watch for changes in your themes and recompile assets when needed"
|
help="Watch for changes in your themes and recompile assets when needed"
|
||||||
)
|
)
|
||||||
@ -65,12 +69,14 @@ def watchthemes(root, edx_platform_path, edx_platform_settings):
|
|||||||
"--no-deps", "lms", "openedx-assets", "watch-themes", "--env", "dev"
|
"--no-deps", "lms", "openedx-assets", "watch-themes", "--env", "dev"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def docker_compose_run_with_port(root, edx_platform_path, edx_platform_settings, port, *command):
|
def docker_compose_run_with_port(root, edx_platform_path, edx_platform_settings, port, *command):
|
||||||
docker_compose_run(
|
docker_compose_run(
|
||||||
root, edx_platform_path, edx_platform_settings,
|
root, edx_platform_path, edx_platform_settings,
|
||||||
"-p", "{port}:{port}".format(port=port), *command
|
"-p", "{port}:{port}".format(port=port), *command
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def docker_compose_run(root, edx_platform_path, edx_platform_settings, *command):
|
def docker_compose_run(root, edx_platform_path, edx_platform_settings, *command):
|
||||||
run_command = [
|
run_command = [
|
||||||
"run", "--rm",
|
"run", "--rm",
|
||||||
@ -85,6 +91,7 @@ def docker_compose_run(root, edx_platform_path, edx_platform_settings, *command)
|
|||||||
run_command += command
|
run_command += command
|
||||||
docker_compose(root, *run_command)
|
docker_compose(root, *run_command)
|
||||||
|
|
||||||
|
|
||||||
def docker_compose(root, *command):
|
def docker_compose(root, *command):
|
||||||
return utils.docker_compose(
|
return utils.docker_compose(
|
||||||
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
||||||
@ -92,9 +99,11 @@ def docker_compose(root, *command):
|
|||||||
*command
|
*command
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def service_port(service):
|
def service_port(service):
|
||||||
return 8000 if service == "lms" else 8001
|
return 8000 if service == "lms" else 8001
|
||||||
|
|
||||||
|
|
||||||
dev.add_command(run)
|
dev.add_command(run)
|
||||||
dev.add_command(runserver)
|
dev.add_command(runserver)
|
||||||
dev.add_command(stop)
|
dev.add_command(stop)
|
||||||
|
@ -63,7 +63,6 @@ def render_dict(config):
|
|||||||
rendered[key] = value
|
rendered[key] = value
|
||||||
for k, v in rendered.items():
|
for k, v in rendered.items():
|
||||||
config[k] = v
|
config[k] = v
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def render_str(config, text):
|
def render_str(config, text):
|
||||||
@ -146,9 +145,9 @@ def walk_templates(root, target):
|
|||||||
def is_part_of_env(path):
|
def is_part_of_env(path):
|
||||||
basename = os.path.basename(path)
|
basename = os.path.basename(path)
|
||||||
return not (
|
return not (
|
||||||
basename.startswith(".") or
|
basename.startswith(".")
|
||||||
basename.endswith(".pyc") or
|
or basename.endswith(".pyc")
|
||||||
basename == "__pycache__"
|
or basename == "__pycache__"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,10 +6,12 @@ from . import fmt
|
|||||||
from . import opts
|
from . import opts
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
@click.group(short_help="Manage docker images")
|
@click.group(short_help="Manage docker images")
|
||||||
def images():
|
def images_command():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
OPENEDX_IMAGES = ["openedx", "forum", "notes", "xqueue", "android"]
|
OPENEDX_IMAGES = ["openedx", "forum", "notes", "xqueue", "android"]
|
||||||
VENDOR_IMAGES = ["elasticsearch", "memcached", "mongodb", "mysql", "nginx", "rabbitmq", "smtp"]
|
VENDOR_IMAGES = ["elasticsearch", "memcached", "mongodb", "mysql", "nginx", "rabbitmq", "smtp"]
|
||||||
argument_openedx_image = click.argument(
|
argument_openedx_image = click.argument(
|
||||||
@ -19,6 +21,7 @@ argument_image = click.argument(
|
|||||||
"image", type=click.Choice(["all"] + OPENEDX_IMAGES + VENDOR_IMAGES),
|
"image", type=click.Choice(["all"] + OPENEDX_IMAGES + VENDOR_IMAGES),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
short_help="Build docker images",
|
short_help="Build docker images",
|
||||||
help="Build the docker images necessary for an Open edX platform."
|
help="Build the docker images necessary for an Open edX platform."
|
||||||
@ -31,8 +34,7 @@ argument_image = click.argument(
|
|||||||
)
|
)
|
||||||
def build(root, image, build_arg):
|
def build(root, image, build_arg):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
for image in openedx_image_names(config, image):
|
for tag in openedx_image_tags(config, image):
|
||||||
tag = get_tag(config, image)
|
|
||||||
click.echo(fmt.info("Building image {}".format(tag)))
|
click.echo(fmt.info("Building image {}".format(tag)))
|
||||||
command = [
|
command = [
|
||||||
"build", "-t", tag,
|
"build", "-t", tag,
|
||||||
@ -44,26 +46,28 @@ def build(root, image, build_arg):
|
|||||||
]
|
]
|
||||||
utils.docker(*command)
|
utils.docker(*command)
|
||||||
|
|
||||||
|
|
||||||
@click.command(short_help="Pull images from the Docker registry")
|
@click.command(short_help="Pull images from the Docker registry")
|
||||||
@opts.root
|
@opts.root
|
||||||
@argument_image
|
@argument_image
|
||||||
def pull(root, image):
|
def pull(root, image):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
for image in image_names(config, image):
|
for img in image_names(config, image):
|
||||||
tag = get_tag(config, image)
|
tag = get_tag(config, img)
|
||||||
click.echo(fmt.info("Pulling image {}".format(tag)))
|
click.echo(fmt.info("Pulling image {}".format(tag)))
|
||||||
utils.execute("docker", "pull", tag)
|
utils.execute("docker", "pull", tag)
|
||||||
|
|
||||||
|
|
||||||
@click.command(short_help="Push images to the Docker registry")
|
@click.command(short_help="Push images to the Docker registry")
|
||||||
@opts.root
|
@opts.root
|
||||||
@argument_openedx_image
|
@argument_openedx_image
|
||||||
def push(root, image):
|
def push(root, image):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
for image in openedx_image_names(config, image):
|
for tag in openedx_image_tags(config, image):
|
||||||
tag = get_tag(config, image)
|
|
||||||
click.echo(fmt.info("Pushing image {}".format(tag)))
|
click.echo(fmt.info("Pushing image {}".format(tag)))
|
||||||
utils.execute("docker", "push", tag)
|
utils.execute("docker", "push", tag)
|
||||||
|
|
||||||
|
|
||||||
def get_tag(config, name):
|
def get_tag(config, name):
|
||||||
image = config["DOCKER_IMAGE_" + name.upper()]
|
image = config["DOCKER_IMAGE_" + name.upper()]
|
||||||
return "{registry}{image}".format(
|
return "{registry}{image}".format(
|
||||||
@ -71,9 +75,16 @@ def get_tag(config, name):
|
|||||||
image=image,
|
image=image,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def image_names(config, image):
|
def image_names(config, image):
|
||||||
return openedx_image_names(config, image) + vendor_image_names(config, image)
|
return openedx_image_names(config, image) + vendor_image_names(config, image)
|
||||||
|
|
||||||
|
|
||||||
|
def openedx_image_tags(config, image):
|
||||||
|
for img in openedx_image_names(config, image):
|
||||||
|
yield get_tag(config, img)
|
||||||
|
|
||||||
|
|
||||||
def openedx_image_names(config, image):
|
def openedx_image_names(config, image):
|
||||||
if image == "all":
|
if image == "all":
|
||||||
images = OPENEDX_IMAGES[:]
|
images = OPENEDX_IMAGES[:]
|
||||||
@ -84,6 +95,7 @@ def openedx_image_names(config, image):
|
|||||||
return images
|
return images
|
||||||
return [image]
|
return [image]
|
||||||
|
|
||||||
|
|
||||||
def vendor_image_names(config, image):
|
def vendor_image_names(config, image):
|
||||||
if image == "all":
|
if image == "all":
|
||||||
images = VENDOR_IMAGES[:]
|
images = VENDOR_IMAGES[:]
|
||||||
@ -100,6 +112,7 @@ def vendor_image_names(config, image):
|
|||||||
return images
|
return images
|
||||||
return [image]
|
return [image]
|
||||||
|
|
||||||
images.add_command(build)
|
|
||||||
images.add_command(pull)
|
images_command.add_command(build)
|
||||||
images.add_command(push)
|
images_command.add_command(pull)
|
||||||
|
images_command.add_command(push)
|
||||||
|
23
tutor/k8s.py
23
tutor/k8s.py
@ -13,6 +13,7 @@ from . import utils
|
|||||||
def k8s():
|
def k8s():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Configure and run Open edX from scratch"
|
help="Configure and run Open edX from scratch"
|
||||||
)
|
)
|
||||||
@ -27,6 +28,7 @@ def quickstart(root):
|
|||||||
click.echo(fmt.title("Running migrations. NOTE: this might fail. If it does, please retry 'tutor k8s databases' later"))
|
click.echo(fmt.title("Running migrations. NOTE: this might fail. If it does, please retry 'tutor k8s databases' later"))
|
||||||
databases.callback(root)
|
databases.callback(root)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Run all configured Open edX services")
|
@click.command(help="Run all configured Open edX services")
|
||||||
@opts.root
|
@opts.root
|
||||||
def start(root):
|
def start(root):
|
||||||
@ -45,10 +47,12 @@ def start(root):
|
|||||||
kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "services.yml"))
|
kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "services.yml"))
|
||||||
kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "deployments.yml"))
|
kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "deployments.yml"))
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Stop a running platform")
|
@click.command(help="Stop a running platform")
|
||||||
def stop():
|
def stop():
|
||||||
kubectl("delete", "deployments,services,ingress,configmaps", "--all")
|
kubectl("delete", "deployments,services,ingress,configmaps", "--all")
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Completely delete an existing platform")
|
@click.command(help="Completely delete an existing platform")
|
||||||
@click.option("-y", "--yes", is_flag=True, help="Do not ask for confirmation")
|
@click.option("-y", "--yes", is_flag=True, help="Do not ask for confirmation")
|
||||||
def delete(yes):
|
def delete(yes):
|
||||||
@ -56,6 +60,7 @@ def delete(yes):
|
|||||||
click.confirm('Are you sure you want to delete the platform? All data will be removed.', abort=True)
|
click.confirm('Are you sure you want to delete the platform? All data will be removed.', abort=True)
|
||||||
kubectl("delete", "namespace", K8s.NAMESPACE)
|
kubectl("delete", "namespace", K8s.NAMESPACE)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Create databases and run database migrations",
|
help="Create databases and run database migrations",
|
||||||
)
|
)
|
||||||
@ -63,6 +68,7 @@ def delete(yes):
|
|||||||
def databases(root):
|
def databases(root):
|
||||||
scripts.migrate(root, run_bash)
|
scripts.migrate(root, run_bash)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Create an Open edX user and interactively set their password")
|
@click.command(help="Create an Open edX user and interactively set their password")
|
||||||
@opts.root
|
@opts.root
|
||||||
@click.option("--superuser", is_flag=True, help="Make superuser")
|
@click.option("--superuser", is_flag=True, help="Make superuser")
|
||||||
@ -72,6 +78,7 @@ def databases(root):
|
|||||||
def createuser(root, superuser, staff, name, email):
|
def createuser(root, superuser, staff, name, email):
|
||||||
scripts.create_user(root, run_bash, superuser, staff, name, email)
|
scripts.create_user(root, run_bash, superuser, staff, name, email)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Import the demo course")
|
@click.command(help="Import the demo course")
|
||||||
@opts.root
|
@opts.root
|
||||||
def importdemocourse(root):
|
def importdemocourse(root):
|
||||||
@ -80,6 +87,7 @@ def importdemocourse(root):
|
|||||||
click.echo(fmt.info("Re-indexing courses"))
|
click.echo(fmt.info("Re-indexing courses"))
|
||||||
indexcourses.callback(root)
|
indexcourses.callback(root)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Re-index courses for better searching")
|
@click.command(help="Re-index courses for better searching")
|
||||||
@opts.root
|
@opts.root
|
||||||
def indexcourses(root):
|
def indexcourses(root):
|
||||||
@ -87,24 +95,26 @@ def indexcourses(root):
|
|||||||
# I'm not quite sure the settings are correctly picked up. Which is weird because migrations work very well.
|
# I'm not quite sure the settings are correctly picked up. Which is weird because migrations work very well.
|
||||||
scripts.index_courses(root, run_bash)
|
scripts.index_courses(root, run_bash)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Launch a shell in LMS or CMS",
|
help="Launch a shell in LMS or CMS",
|
||||||
)
|
)
|
||||||
@opts.root
|
|
||||||
@click.argument("service", type=click.Choice(["lms", "cms"]))
|
@click.argument("service", type=click.Choice(["lms", "cms"]))
|
||||||
def shell(root, service):
|
def shell(service):
|
||||||
K8s().execute(service, "bash")
|
K8s().execute(service, "bash")
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Create a Kubernetesadmin user")
|
@click.command(help="Create a Kubernetesadmin user")
|
||||||
@opts.root
|
@opts.root
|
||||||
def adminuser(root):
|
def adminuser(root):
|
||||||
utils.kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "adminuser.yml"))
|
utils.kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "adminuser.yml"))
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Print the Kubernetes admin user token")
|
@click.command(help="Print the Kubernetes admin user token")
|
||||||
@opts.root
|
def admintoken():
|
||||||
def admintoken(root):
|
|
||||||
click.echo(K8s().admin_token())
|
click.echo(K8s().admin_token())
|
||||||
|
|
||||||
|
|
||||||
def kubectl(*command):
|
def kubectl(*command):
|
||||||
"""
|
"""
|
||||||
Run kubectl commands in the right namespace. Also, errors are completely
|
Run kubectl commands in the right namespace. Also, errors are completely
|
||||||
@ -116,6 +126,7 @@ def kubectl(*command):
|
|||||||
]
|
]
|
||||||
kubectl_no_fail(*args)
|
kubectl_no_fail(*args)
|
||||||
|
|
||||||
|
|
||||||
def kubectl_no_fail(*command):
|
def kubectl_no_fail(*command):
|
||||||
"""
|
"""
|
||||||
Run kubectl commands and ignore exceptions, to avoid stopping on
|
Run kubectl commands and ignore exceptions, to avoid stopping on
|
||||||
@ -164,9 +175,11 @@ class K8s:
|
|||||||
podname = self.pod_name(app)
|
podname = self.pod_name(app)
|
||||||
kubectl_no_fail("exec", "--namespace", self.NAMESPACE, "-it", podname, "--", *command)
|
kubectl_no_fail("exec", "--namespace", self.NAMESPACE, "-it", podname, "--", *command)
|
||||||
|
|
||||||
def run_bash(root, service, command):
|
|
||||||
|
def run_bash(root, service, command): # pylint: disable=unused-argument
|
||||||
K8s().execute(service, "bash", "-e", "-c", command)
|
K8s().execute(service, "bash", "-e", "-c", command)
|
||||||
|
|
||||||
|
|
||||||
k8s.add_command(quickstart)
|
k8s.add_command(quickstart)
|
||||||
k8s.add_command(start)
|
k8s.add_command(start)
|
||||||
k8s.add_command(stop)
|
k8s.add_command(stop)
|
||||||
|
@ -21,6 +21,7 @@ from . import utils
|
|||||||
def local():
|
def local():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Configure and run Open edX from scratch")
|
@click.command(help="Configure and run Open edX from scratch")
|
||||||
@click.option("-p", "--pullimages", "pullimages_", is_flag=True, help="Update docker images")
|
@click.option("-p", "--pullimages", "pullimages_", is_flag=True, help="Update docker images")
|
||||||
@opts.root
|
@opts.root
|
||||||
@ -39,12 +40,14 @@ def quickstart(pullimages_, root):
|
|||||||
click.echo(fmt.title("Starting the platform in detached mode"))
|
click.echo(fmt.title("Starting the platform in detached mode"))
|
||||||
start.callback(root, True)
|
start.callback(root, True)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Update docker images")
|
@click.command(help="Update docker images")
|
||||||
@opts.root
|
@opts.root
|
||||||
def pullimages(root):
|
def pullimages(root):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
docker_compose(root, config, "pull")
|
docker_compose(root, config, "pull")
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Run all configured Open edX services")
|
@click.command(help="Run all configured Open edX services")
|
||||||
@opts.root
|
@opts.root
|
||||||
@click.option("-d", "--detach", is_flag=True, help="Start in daemon mode")
|
@click.option("-d", "--detach", is_flag=True, help="Start in daemon mode")
|
||||||
@ -97,6 +100,7 @@ def restart(root, service):
|
|||||||
command += [service]
|
command += [service]
|
||||||
docker_compose(root, config, *command)
|
docker_compose(root, config, *command)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Run a command in one of the containers",
|
help="Run a command in one of the containers",
|
||||||
context_settings={"ignore_unknown_options": True},
|
context_settings={"ignore_unknown_options": True},
|
||||||
@ -118,6 +122,7 @@ def run(root, service, command, args):
|
|||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
docker_compose(root, config, *run_command)
|
docker_compose(root, config, *run_command)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Create databases and run database migrations",
|
help="Create databases and run database migrations",
|
||||||
)
|
)
|
||||||
@ -126,6 +131,7 @@ def databases(root):
|
|||||||
init_mysql(root)
|
init_mysql(root)
|
||||||
scripts.migrate(root, run_bash)
|
scripts.migrate(root, run_bash)
|
||||||
|
|
||||||
|
|
||||||
def init_mysql(root):
|
def init_mysql(root):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
if not config['ACTIVATE_MYSQL']:
|
if not config['ACTIVATE_MYSQL']:
|
||||||
@ -139,20 +145,23 @@ def init_mysql(root):
|
|||||||
click.echo(fmt.info(" waiting for mysql initialization"))
|
click.echo(fmt.info(" waiting for mysql initialization"))
|
||||||
# TODO this is duplicate code with the docker_compose function. We
|
# TODO this is duplicate code with the docker_compose function. We
|
||||||
# should rely on a dedicated function in utils module.
|
# should rely on a dedicated function in utils module.
|
||||||
logs = subprocess.check_output([
|
mysql_logs = subprocess.check_output([
|
||||||
"docker-compose", "-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
"docker-compose", "-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
||||||
"--project-name", config["LOCAL_PROJECT_NAME"], "logs", "mysql",
|
"--project-name", config["LOCAL_PROJECT_NAME"], "logs", "mysql",
|
||||||
])
|
])
|
||||||
if b"MySQL init process done. Ready for start up." in logs:
|
# pylint: disable=unsupported-membership-test
|
||||||
|
if b"MySQL init process done. Ready for start up." in mysql_logs:
|
||||||
click.echo(fmt.info("MySQL database initialized"))
|
click.echo(fmt.info("MySQL database initialized"))
|
||||||
docker_compose(root, config, "stop", "mysql")
|
docker_compose(root, config, "stop", "mysql")
|
||||||
return
|
return
|
||||||
sleep(4)
|
sleep(4)
|
||||||
|
|
||||||
|
|
||||||
@click.group(help="Manage https certificates")
|
@click.group(help="Manage https certificates")
|
||||||
def https():
|
def https():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Create https certificates", name="create")
|
@click.command(help="Create https certificates", name="create")
|
||||||
@opts.root
|
@opts.root
|
||||||
def https_create(root):
|
def https_create(root):
|
||||||
@ -188,6 +197,7 @@ See the official certbot documentation for your platform: https://certbot.eff.or
|
|||||||
"-e", "-c", script,
|
"-e", "-c", script,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Renew https certificates", name="renew")
|
@click.command(help="Renew https certificates", name="renew")
|
||||||
@opts.root
|
@opts.root
|
||||||
def https_renew(root):
|
def https_renew(root):
|
||||||
@ -211,6 +221,7 @@ See the official certbot documentation for your platform: https://certbot.eff.or
|
|||||||
]
|
]
|
||||||
utils.docker_run(*docker_run)
|
utils.docker_run(*docker_run)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="View output from containers")
|
@click.command(help="View output from containers")
|
||||||
@opts.root
|
@opts.root
|
||||||
@click.option("-f", "--follow", is_flag=True, help="Follow log output")
|
@click.option("-f", "--follow", is_flag=True, help="Follow log output")
|
||||||
@ -226,6 +237,7 @@ def logs(root, follow, tail, service):
|
|||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
docker_compose(root, config, *command)
|
docker_compose(root, config, *command)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Create an Open edX user and interactively set their password")
|
@click.command(help="Create an Open edX user and interactively set their password")
|
||||||
@opts.root
|
@opts.root
|
||||||
@click.option("--superuser", is_flag=True, help="Make superuser")
|
@click.option("--superuser", is_flag=True, help="Make superuser")
|
||||||
@ -237,6 +249,7 @@ def createuser(root, superuser, staff, name, email):
|
|||||||
check_service_is_activated(config, "lms")
|
check_service_is_activated(config, "lms")
|
||||||
scripts.create_user(root, run_bash, superuser, staff, name, email)
|
scripts.create_user(root, run_bash, superuser, staff, name, email)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Import the demo course")
|
@click.command(help="Import the demo course")
|
||||||
@opts.root
|
@opts.root
|
||||||
def importdemocourse(root):
|
def importdemocourse(root):
|
||||||
@ -247,6 +260,7 @@ def importdemocourse(root):
|
|||||||
click.echo(fmt.info("Re-indexing courses"))
|
click.echo(fmt.info("Re-indexing courses"))
|
||||||
indexcourses.callback(root)
|
indexcourses.callback(root)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="Re-index courses for better searching")
|
@click.command(help="Re-index courses for better searching")
|
||||||
@opts.root
|
@opts.root
|
||||||
def indexcourses(root):
|
def indexcourses(root):
|
||||||
@ -254,6 +268,7 @@ def indexcourses(root):
|
|||||||
check_service_is_activated(config, "cms")
|
check_service_is_activated(config, "cms")
|
||||||
scripts.index_courses(root, run_bash)
|
scripts.index_courses(root, run_bash)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
help="Run Portainer (https://portainer.io), a UI for container supervision",
|
help="Run Portainer (https://portainer.io), a UI for container supervision",
|
||||||
short_help="Run Portainer, a UI for container supervision",
|
short_help="Run Portainer, a UI for container supervision",
|
||||||
@ -271,14 +286,17 @@ def portainer(root, port):
|
|||||||
click.echo(fmt.info("View the Portainer UI at http://localhost:{port}".format(port=port)))
|
click.echo(fmt.info("View the Portainer UI at http://localhost:{port}".format(port=port)))
|
||||||
utils.docker_run(*docker_run)
|
utils.docker_run(*docker_run)
|
||||||
|
|
||||||
|
|
||||||
def check_service_is_activated(config, service):
|
def check_service_is_activated(config, service):
|
||||||
if not config["ACTIVATE_" + service.upper()]:
|
if not config["ACTIVATE_" + service.upper()]:
|
||||||
raise exceptions.TutorError("This command may only be executed on the server where the {} is running".format(service))
|
raise exceptions.TutorError("This command may only be executed on the server where the {} is running".format(service))
|
||||||
|
|
||||||
|
|
||||||
def run_bash(root, service, command):
|
def run_bash(root, service, command):
|
||||||
config = tutor_config.load(root)
|
config = tutor_config.load(root)
|
||||||
docker_compose(root, config, "run", "--rm", service, "bash", "-e", "-c", command)
|
docker_compose(root, config, "run", "--rm", service, "bash", "-e", "-c", command)
|
||||||
|
|
||||||
|
|
||||||
def docker_compose(root, config, *command):
|
def docker_compose(root, config, *command):
|
||||||
return utils.docker_compose(
|
return utils.docker_compose(
|
||||||
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
||||||
@ -286,6 +304,7 @@ def docker_compose(root, config, *command):
|
|||||||
*command
|
*command
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
https.add_command(https_create)
|
https.add_command(https_create)
|
||||||
https.add_command(https_renew)
|
https.add_command(https_renew)
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import click
|
import click
|
||||||
import click_repl
|
import click_repl
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
@click.command(
|
||||||
short_help="Interactive shell",
|
short_help="Interactive shell",
|
||||||
help="Launch an interactive shell for launching Tutor commands"
|
help="Launch an interactive shell for launching Tutor commands"
|
||||||
@ -14,5 +15,5 @@ Type <ctrl-d> to exit.""")
|
|||||||
try:
|
try:
|
||||||
click_repl.repl(click.get_current_context())
|
click_repl.repl(click.get_current_context())
|
||||||
return # this happens on a ctrl+d
|
return # this happens on a ctrl+d
|
||||||
except Exception:
|
except Exception: # pylint: disable=broad-except
|
||||||
pass
|
pass
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import click
|
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
import string
|
import string
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
from . import exceptions
|
from . import exceptions
|
||||||
from . import fmt
|
from . import fmt
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ from . import fmt
|
|||||||
def random_string(length):
|
def random_string(length):
|
||||||
return "".join([random.choice(string.ascii_letters + string.digits) for _ in range(length)])
|
return "".join([random.choice(string.ascii_letters + string.digits) for _ in range(length)])
|
||||||
|
|
||||||
|
|
||||||
def common_domain(d1, d2):
|
def common_domain(d1, d2):
|
||||||
"""
|
"""
|
||||||
Return the common domain between two domain names.
|
Return the common domain between two domain names.
|
||||||
@ -27,19 +29,23 @@ def common_domain(d1, d2):
|
|||||||
break
|
break
|
||||||
return ".".join(common[::-1])
|
return ".".join(common[::-1])
|
||||||
|
|
||||||
|
|
||||||
def docker_run(*command):
|
def docker_run(*command):
|
||||||
return docker("run", "--rm", "-it", *command)
|
return docker("run", "--rm", "-it", *command)
|
||||||
|
|
||||||
|
|
||||||
def docker(*command):
|
def docker(*command):
|
||||||
if shutil.which("docker") is None:
|
if shutil.which("docker") is None:
|
||||||
raise exceptions.TutorError("docker is not installed. Please follow instructions from https://docs.docker.com/install/")
|
raise exceptions.TutorError("docker is not installed. Please follow instructions from https://docs.docker.com/install/")
|
||||||
return execute("docker", *command)
|
return execute("docker", *command)
|
||||||
|
|
||||||
|
|
||||||
def docker_compose(*command):
|
def docker_compose(*command):
|
||||||
if shutil.which("docker-compose") is None:
|
if shutil.which("docker-compose") is None:
|
||||||
raise exceptions.TutorError("docker-compose is not installed. Please follow instructions from https://docs.docker.com/compose/install/")
|
raise exceptions.TutorError("docker-compose is not installed. Please follow instructions from https://docs.docker.com/compose/install/")
|
||||||
return execute("docker-compose", *command)
|
return execute("docker-compose", *command)
|
||||||
|
|
||||||
|
|
||||||
def kubectl(*command):
|
def kubectl(*command):
|
||||||
if shutil.which("kubectl") is None:
|
if shutil.which("kubectl") is None:
|
||||||
raise exceptions.TutorError(
|
raise exceptions.TutorError(
|
||||||
@ -47,6 +53,7 @@ def kubectl(*command):
|
|||||||
)
|
)
|
||||||
return execute("kubectl", *command)
|
return execute("kubectl", *command)
|
||||||
|
|
||||||
|
|
||||||
def execute(*command):
|
def execute(*command):
|
||||||
click.echo(fmt.command(" ".join(command)))
|
click.echo(fmt.command(" ".join(command)))
|
||||||
with subprocess.Popen(command) as p:
|
with subprocess.Popen(command) as p:
|
||||||
|
Loading…
Reference in New Issue
Block a user