6
0
mirror of https://github.com/ChristianLight/tutor.git synced 2024-11-05 21:07:50 +00:00

Run pylint on code base

This commit is contained in:
Régis Behmo 2019-04-23 09:57:55 +02:00
parent ce1bb05d8e
commit 207229e16e
9 changed files with 105 additions and 42 deletions

View File

@ -6,9 +6,9 @@ import click_repl
from .__about__ import __version__
from .android import android
from .config import config
from .config import config_command
from .dev import dev
from .images import images
from .images import images_command
from .k8s import k8s
from .local import local
from .ui import ui
@ -24,11 +24,13 @@ def main():
sys.stderr.write(fmt.error("Error: {}\n".format(e.args[0])))
sys.exit(1)
@click.group(context_settings={'help_option_names': ['-h', '--help', 'help']})
@click.version_option(version=__version__)
def cli():
pass
@click.command(
help="Print this help",
name="help",
@ -37,9 +39,10 @@ def print_help():
with click.Context(cli) as context:
click.echo(cli.get_help(context))
click_repl.register_repl(cli, name="ui")
cli.add_command(images)
cli.add_command(config)
cli.add_command(images_command, name="images")
cli.add_command(config_command, name="config")
cli.add_command(local)
cli.add_command(dev)
cli.add_command(android)

View File

@ -17,7 +17,7 @@ from .__about__ import __version__
short_help="Configure Open edX",
help="""Configure Open edX and store configuration values in $TUTOR_ROOT/config.yml"""
)
def config():
def config_command():
pass
@ -33,8 +33,7 @@ def save_command(root, silent1, silent2, set_):
def save(root, silent=False, keyvalues=None):
keyvalues = keyvalues or []
config = {}
load_current(config, root)
config = load_current(root)
for k, v in keyvalues:
config[k] = v
if not silent:
@ -57,8 +56,7 @@ def printroot(root):
@opts.root
@click.argument("key")
def printvalue(root, key):
config = {}
load_current(config, root)
config = load_current(root)
load_defaults(config)
try:
print(config[key])
@ -71,8 +69,7 @@ def load(root):
Load configuration, and generate it interactively if the file does not
exist.
"""
config = {}
load_current(config, root)
config = load_current(root)
should_update_env = False
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)
load_base(config, root)
config = {}
load_base(config)
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"))
for k, v in base.items():
config[k] = v
def load_env(config, root):
def load_env(config):
base_config = serialize.load(env.read("config-base.yml"))
default_config = serialize.load(env.read("config-defaults.yml"))
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")
config.add_command(save_command, name="save")
config.add_command(printroot)
config.add_command(printvalue)
config_command.add_command(save_command, name="save")
config_command.add_command(printroot)
config_command.add_command(printvalue)

View File

@ -13,6 +13,7 @@ from . import utils
def dev():
pass
@click.command(
help="Run a command in one of the containers",
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
)
@click.command(
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),
)
@click.command(help="Stop a running development platform",)
@opts.root
def stop(root):
docker_compose(root, "rm", "--stop", "--force")
@click.command(
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"
)
def docker_compose_run_with_port(root, edx_platform_path, edx_platform_settings, port, *command):
docker_compose_run(
root, edx_platform_path, edx_platform_settings,
"-p", "{port}:{port}".format(port=port), *command
)
def docker_compose_run(root, edx_platform_path, edx_platform_settings, *command):
run_command = [
"run", "--rm",
@ -85,6 +91,7 @@ def docker_compose_run(root, edx_platform_path, edx_platform_settings, *command)
run_command += command
docker_compose(root, *run_command)
def docker_compose(root, *command):
return utils.docker_compose(
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
@ -92,9 +99,11 @@ def docker_compose(root, *command):
*command
)
def service_port(service):
return 8000 if service == "lms" else 8001
dev.add_command(run)
dev.add_command(runserver)
dev.add_command(stop)

View File

@ -63,7 +63,6 @@ def render_dict(config):
rendered[key] = value
for k, v in rendered.items():
config[k] = v
pass
def render_str(config, text):
@ -146,9 +145,9 @@ def walk_templates(root, target):
def is_part_of_env(path):
basename = os.path.basename(path)
return not (
basename.startswith(".") or
basename.endswith(".pyc") or
basename == "__pycache__"
basename.startswith(".")
or basename.endswith(".pyc")
or basename == "__pycache__"
)

View File

@ -6,10 +6,12 @@ from . import fmt
from . import opts
from . import utils
@click.group(short_help="Manage docker images")
def images():
def images_command():
pass
OPENEDX_IMAGES = ["openedx", "forum", "notes", "xqueue", "android"]
VENDOR_IMAGES = ["elasticsearch", "memcached", "mongodb", "mysql", "nginx", "rabbitmq", "smtp"]
argument_openedx_image = click.argument(
@ -19,6 +21,7 @@ argument_image = click.argument(
"image", type=click.Choice(["all"] + OPENEDX_IMAGES + VENDOR_IMAGES),
)
@click.command(
short_help="Build docker images",
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):
config = tutor_config.load(root)
for image in openedx_image_names(config, image):
tag = get_tag(config, image)
for tag in openedx_image_tags(config, image):
click.echo(fmt.info("Building image {}".format(tag)))
command = [
"build", "-t", tag,
@ -44,26 +46,28 @@ def build(root, image, build_arg):
]
utils.docker(*command)
@click.command(short_help="Pull images from the Docker registry")
@opts.root
@argument_image
def pull(root, image):
config = tutor_config.load(root)
for image in image_names(config, image):
tag = get_tag(config, image)
for img in image_names(config, image):
tag = get_tag(config, img)
click.echo(fmt.info("Pulling image {}".format(tag)))
utils.execute("docker", "pull", tag)
@click.command(short_help="Push images to the Docker registry")
@opts.root
@argument_openedx_image
def push(root, image):
config = tutor_config.load(root)
for image in openedx_image_names(config, image):
tag = get_tag(config, image)
for tag in openedx_image_tags(config, image):
click.echo(fmt.info("Pushing image {}".format(tag)))
utils.execute("docker", "push", tag)
def get_tag(config, name):
image = config["DOCKER_IMAGE_" + name.upper()]
return "{registry}{image}".format(
@ -71,9 +75,16 @@ def get_tag(config, name):
image=image,
)
def 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):
if image == "all":
images = OPENEDX_IMAGES[:]
@ -84,6 +95,7 @@ def openedx_image_names(config, image):
return images
return [image]
def vendor_image_names(config, image):
if image == "all":
images = VENDOR_IMAGES[:]
@ -100,6 +112,7 @@ def vendor_image_names(config, image):
return images
return [image]
images.add_command(build)
images.add_command(pull)
images.add_command(push)
images_command.add_command(build)
images_command.add_command(pull)
images_command.add_command(push)

View File

@ -13,6 +13,7 @@ from . import utils
def k8s():
pass
@click.command(
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"))
databases.callback(root)
@click.command(help="Run all configured Open edX services")
@opts.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", "deployments.yml"))
@click.command(help="Stop a running platform")
def stop():
kubectl("delete", "deployments,services,ingress,configmaps", "--all")
@click.command(help="Completely delete an existing platform")
@click.option("-y", "--yes", is_flag=True, help="Do not ask for confirmation")
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)
kubectl("delete", "namespace", K8s.NAMESPACE)
@click.command(
help="Create databases and run database migrations",
)
@ -63,6 +68,7 @@ def delete(yes):
def databases(root):
scripts.migrate(root, run_bash)
@click.command(help="Create an Open edX user and interactively set their password")
@opts.root
@click.option("--superuser", is_flag=True, help="Make superuser")
@ -72,6 +78,7 @@ def databases(root):
def createuser(root, superuser, staff, name, email):
scripts.create_user(root, run_bash, superuser, staff, name, email)
@click.command(help="Import the demo course")
@opts.root
def importdemocourse(root):
@ -80,6 +87,7 @@ def importdemocourse(root):
click.echo(fmt.info("Re-indexing courses"))
indexcourses.callback(root)
@click.command(help="Re-index courses for better searching")
@opts.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.
scripts.index_courses(root, run_bash)
@click.command(
help="Launch a shell in LMS or CMS",
)
@opts.root
@click.argument("service", type=click.Choice(["lms", "cms"]))
def shell(root, service):
def shell(service):
K8s().execute(service, "bash")
@click.command(help="Create a Kubernetesadmin user")
@opts.root
def adminuser(root):
utils.kubectl("create", "-f", tutor_env.pathjoin(root, "k8s", "adminuser.yml"))
@click.command(help="Print the Kubernetes admin user token")
@opts.root
def admintoken(root):
def admintoken():
click.echo(K8s().admin_token())
def kubectl(*command):
"""
Run kubectl commands in the right namespace. Also, errors are completely
@ -116,6 +126,7 @@ def kubectl(*command):
]
kubectl_no_fail(*args)
def kubectl_no_fail(*command):
"""
Run kubectl commands and ignore exceptions, to avoid stopping on
@ -164,9 +175,11 @@ class K8s:
podname = self.pod_name(app)
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.add_command(quickstart)
k8s.add_command(start)
k8s.add_command(stop)

View File

@ -21,6 +21,7 @@ from . import utils
def local():
pass
@click.command(help="Configure and run Open edX from scratch")
@click.option("-p", "--pullimages", "pullimages_", is_flag=True, help="Update docker images")
@opts.root
@ -39,12 +40,14 @@ def quickstart(pullimages_, root):
click.echo(fmt.title("Starting the platform in detached mode"))
start.callback(root, True)
@click.command(help="Update docker images")
@opts.root
def pullimages(root):
config = tutor_config.load(root)
docker_compose(root, config, "pull")
@click.command(help="Run all configured Open edX services")
@opts.root
@click.option("-d", "--detach", is_flag=True, help="Start in daemon mode")
@ -97,6 +100,7 @@ def restart(root, service):
command += [service]
docker_compose(root, config, *command)
@click.command(
help="Run a command in one of the containers",
context_settings={"ignore_unknown_options": True},
@ -118,6 +122,7 @@ def run(root, service, command, args):
config = tutor_config.load(root)
docker_compose(root, config, *run_command)
@click.command(
help="Create databases and run database migrations",
)
@ -126,6 +131,7 @@ def databases(root):
init_mysql(root)
scripts.migrate(root, run_bash)
def init_mysql(root):
config = tutor_config.load(root)
if not config['ACTIVATE_MYSQL']:
@ -139,20 +145,23 @@ def init_mysql(root):
click.echo(fmt.info(" waiting for mysql initialization"))
# TODO this is duplicate code with the docker_compose function. We
# 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"),
"--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"))
docker_compose(root, config, "stop", "mysql")
return
sleep(4)
@click.group(help="Manage https certificates")
def https():
pass
@click.command(help="Create https certificates", name="create")
@opts.root
def https_create(root):
@ -188,6 +197,7 @@ See the official certbot documentation for your platform: https://certbot.eff.or
"-e", "-c", script,
)
@click.command(help="Renew https certificates", name="renew")
@opts.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)
@click.command(help="View output from containers")
@opts.root
@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)
docker_compose(root, config, *command)
@click.command(help="Create an Open edX user and interactively set their password")
@opts.root
@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")
scripts.create_user(root, run_bash, superuser, staff, name, email)
@click.command(help="Import the demo course")
@opts.root
def importdemocourse(root):
@ -247,6 +260,7 @@ def importdemocourse(root):
click.echo(fmt.info("Re-indexing courses"))
indexcourses.callback(root)
@click.command(help="Re-index courses for better searching")
@opts.root
def indexcourses(root):
@ -254,6 +268,7 @@ def indexcourses(root):
check_service_is_activated(config, "cms")
scripts.index_courses(root, run_bash)
@click.command(
help="Run Portainer (https://portainer.io), 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)))
utils.docker_run(*docker_run)
def check_service_is_activated(config, service):
if not config["ACTIVATE_" + service.upper()]:
raise exceptions.TutorError("This command may only be executed on the server where the {} is running".format(service))
def run_bash(root, service, command):
config = tutor_config.load(root)
docker_compose(root, config, "run", "--rm", service, "bash", "-e", "-c", command)
def docker_compose(root, config, *command):
return utils.docker_compose(
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
@ -286,6 +304,7 @@ def docker_compose(root, config, *command):
*command
)
https.add_command(https_create)
https.add_command(https_renew)

View File

@ -1,6 +1,7 @@
import click
import click_repl
@click.command(
short_help="Interactive shell",
help="Launch an interactive shell for launching Tutor commands"
@ -14,5 +15,5 @@ Type <ctrl-d> to exit.""")
try:
click_repl.repl(click.get_current_context())
return # this happens on a ctrl+d
except Exception:
except Exception: # pylint: disable=broad-except
pass

View File

@ -1,9 +1,10 @@
import click
import random
import shutil
import string
import subprocess
import click
from . import exceptions
from . import fmt
@ -11,6 +12,7 @@ from . import fmt
def random_string(length):
return "".join([random.choice(string.ascii_letters + string.digits) for _ in range(length)])
def common_domain(d1, d2):
"""
Return the common domain between two domain names.
@ -27,19 +29,23 @@ def common_domain(d1, d2):
break
return ".".join(common[::-1])
def docker_run(*command):
return docker("run", "--rm", "-it", *command)
def docker(*command):
if shutil.which("docker") is None:
raise exceptions.TutorError("docker is not installed. Please follow instructions from https://docs.docker.com/install/")
return execute("docker", *command)
def docker_compose(*command):
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/")
return execute("docker-compose", *command)
def kubectl(*command):
if shutil.which("kubectl") is None:
raise exceptions.TutorError(
@ -47,6 +53,7 @@ def kubectl(*command):
)
return execute("kubectl", *command)
def execute(*command):
click.echo(fmt.command(" ".join(command)))
with subprocess.Popen(command) as p: