Пример #1
0
def ddc_project():
    """Proxy for docker-compose: writes a docker-compose.yml file with the
    configuration of this project, and then run `docker-compose` on it.

    You probably want do run `ddc-project up -d` and `ddc-project logs -f`.
    """
    check_docker()
    setup_logging()
    try:
        project = Project()
    except ValueError:
        click.echo("You need to run this command in a derex project")
        sys.exit(1)
    compose_args, dry_run = ddc_parse_args(sys.argv)
    # If trying to start up containers, first check that needed services are running
    is_start_cmd = any(param in compose_args for param in ["up", "start"])
    if is_start_cmd and not check_services(["mysql", "mongodb", "rabbitmq"]):
        click.echo(
            "Mysql/mongo/rabbitmq services not found.\nMaybe you forgot to run\nddc-services up -d"
        )
        return
    run_compose(list(compose_args),
                project=project,
                dry_run=dry_run,
                exit_afterwards=True)
Пример #2
0
def reset_mysql(project):
    """Reset the discovery mysql database"""
    from derex.runner.docker import check_services
    from derex.runner.docker import wait_for_mysql

    if project.runmode is not ProjectRunMode.debug:
        click.get_current_context().fail(
            "This command can only be run in `debug` runmode")
    if not check_services(["mysql"]):
        click.echo(
            "Mysql service not found.\nMaybe you forgot to run\nddc-services up -d"
        )
        return

    wait_for_mysql()
    restore_dump_path = abspath_from_egg("derex.discovery",
                                         "derex/discovery/restore_dump.py")
    run_compose(
        [
            "run",
            "--rm",
            "-v",
            f"{restore_dump_path}:/openedx/discovery/restore_dump.py",
            "discovery",
            "python",
            "/openedx/discovery/restore_dump.py",
        ],
        project=project,
    )
    return 0
Пример #3
0
def update_minio(old_key: str):
    """Run minio to re-key data with the new secret. The output is very confusing, but it works.
    If you read a red warning and "Rotation complete" at the end, it means rekeying has worked.
    If your read your current SecretKey, it means the current credentials are correct and you don't need
    to update your keys.
    """
    from derex.runner.compose_utils import run_compose

    # We need to stop minio after it's done re-keying. To this end, we use the expect package
    script = "apk add expect --no-cache "
    # We need to make sure the current credentials are not working...
    script += ' && expect -c "spawn /usr/bin/minio server /data; expect "Endpoint" { close; exit 1 }"'
    # ..but the old ones are
    script += f' && if MINIO_SECRET_KEY="{old_key}" expect -c \'spawn /usr/bin/minio server /data; expect "Endpoint" {{ close; exit 1 }}\'; then exit 1; fi'
    script += f' && export MINIO_ACCESS_KEY_OLD="$MINIO_ACCESS_KEY" MINIO_SECRET_KEY_OLD="{old_key}"'
    expected_string = "Rotation complete, please make sure to unset MINIO_ACCESS_KEY_OLD and MINIO_SECRET_KEY_OLD envs"
    script += f" && expect -c 'spawn /usr/bin/minio server /data; expect \"{expected_string}\" {{ close; exit 0 }}'"
    args = [
        "run",
        "--rm",
        "--entrypoint",
        "/bin/sh",
        "-T",
        "minio",
        "-c",
        script,
    ]
    run_compose(args, exit_afterwards=True)
    click.echo(f"Minio server rekeying finished")
Пример #4
0
def ddc_services():
    """Derex docker-compose: run docker-compose with additional parameters.
    Adds docker compose file paths for services and administrative tools.
    If the environment variable DEREX_ADMIN_SERVICES is set to a falsey value,
    only the core ones will be started (mysql, mongodb etc) and the nice-to-have
    will not (portainer and adminer).

    Besides the regular docker-compose options it also accepts the --dry-run
    option; in case it's specified docker-compose will not be invoked, but
    a line will be printed showing what would have been invoked.
    """
    check_docker()
    setup_logging()
    args, dry_run = ddc_parse_args(sys.argv)
    run_compose(args, dry_run=dry_run, exit_afterwards=True)
Пример #5
0
def reset_rabbitmq(project):
    """Create rabbitmq vhost"""
    from derex.runner.compose_utils import run_compose

    vhost = f"{project.name}_edxqueue"
    args = [
        "exec",
        "-T",
        "rabbitmq",
        "sh",
        "-c",
        f"""rabbitmqctl add_vhost {vhost}
        rabbitmqctl set_permissions -p {vhost} guest ".*" ".*" ".*"
        """,
    ]
    run_compose(args)
    click.echo(f"Rabbitmq vhost {vhost} created")
    return 0
Пример #6
0
def refresh_course_metadata(project):
    """Run discovery `refresh_course_metadata` Django command"""
    from derex.runner.docker import check_services

    if not check_services(["elasticsearch"]):
        click.echo(
            "Elasticsearch service not found.\nMaybe you forgot to run\nddc-services up -d"
        )
        return

    run_compose(
        [
            "run", "--rm", "discovery", "python", "manage.py",
            "refresh_course_metadata"
        ],
        project=project,
    )
    return 0
Пример #7
0
def create_index(project):
    """Run discovery `install_es_indexes` Django command"""
    from derex.runner.docker import check_services

    if not check_services(["elasticsearch"]):
        click.echo(
            "Elasticsearch service not found.\nMaybe you forgot to run\nddc-services up -d"
        )
        return

    run_compose(
        [
            "run", "--rm", "discovery", "python", "manage.py",
            "install_es_indexes"
        ],
        project=project,
    )
    return 0
Пример #8
0
def reset_mysql_openedx(project: Project, dry_run: bool = False):
    """Run script from derex/openedx image to reset the mysql db.
    """
    restore_dump_path = abspath_from_egg(
        "derex.runner", "derex/runner/restore_dump.py.source")
    assert (restore_dump_path
            ), "Could not find restore_dump.py in derex.runner distribution"
    run_compose(
        [
            "run",
            "--rm",
            "-v",
            f"{restore_dump_path}:/restore_dump.py",
            "lms",
            "python",
            "/restore_dump.py",
        ],
        project=project,
        dry_run=dry_run,
    )
Пример #9
0
def copy_database(source_db_name: str, destination_db_name: str):
    """
    Copy an existing MySQL database. This actually involves exporting and importing back
    the database with a different name.
    """
    create_database(destination_db_name)
    logger.info(f"Copying database {source_db_name} to {destination_db_name}")
    run_compose([
        "run",
        "--rm",
        "mysql",
        "sh",
        "-c",
        f"""set -ex
                mysqldump -h mysql -u root -psecret {source_db_name} --no-create-db |
                mysql -h mysql --user=root -psecret {destination_db_name}
            """,
    ])
    logger.info(
        f"Successfully copied database {source_db_name} to {destination_db_name}"
    )
Пример #10
0
def compile_theme(project):
    """Compile theme sass files"""
    from derex.runner.compose_utils import run_compose

    if project.themes_dir is None:
        click.echo("No theme directory present in this project")
        return
    themes = ",".join(el.name for el in project.themes_dir.iterdir())
    uid = os.getuid()
    args = [
        "run",
        "--rm",
        "lms",
        "sh",
        "-c",
        f"""set -ex
            export PATH=/openedx/edx-platform/node_modules/.bin:$PATH  # FIXME: this should not be necessary
            paver compile_sass --theme-dirs /openedx/themes --themes {themes}
            chown {uid}:{uid} /openedx/themes/* -R""",
    ]
    run_compose(args, project=DebugBaseImageProject(), exit_afterwards=True)
Пример #11
0
def load_fixtures(project):
    """Load fixtures from the plugin fixtures directory"""
    from derex.runner.compose_utils import run_compose

    fixtures_dir = project.get_plugin_directories(__package__).get("fixtures")
    if fixtures_dir is None:
        click.echo("No fixtures directory present for this plugin")
        return

    load_fixtures_path = abspath_from_egg("derex.discovery",
                                          "derex/discovery/load_fixtures.py")
    compose_args = [
        "run",
        "--rm",
        "-v",
        f"{load_fixtures_path}:/openedx/discovery/load_fixtures.py",
        "discovery",
        "python",
        "/openedx/discovery/load_fixtures.py",
    ]
    run_compose(compose_args, project=project)
    return
Пример #12
0
def update_index(project):
    """Run discovery `update_index` Django command"""
    from derex.runner.docker import check_services

    if not check_services(["elasticsearch"]):
        click.echo(
            "Elasticsearch service not found.\nMaybe you forgot to run\nddc-services up -d"
        )
        return

    run_compose(
        [
            "run",
            "--rm",
            "discovery",
            "python",
            "manage.py",
            "update_index",
            "--disable-change-limit",
        ],
        project=project,
    )
    return 0