예제 #1
0
def build_image(verbose: bool, dry_run: bool, **kwargs) -> None:
    """
    Builds CI image:

      * fixes group permissions for files (to improve caching when umask is 002)
      * converts all the parameters received via kwargs into BuildCIParams (including cache)
      * prints info about the image to build
      * logs int to docker registry on CI if build cache is being executed
      * removes "tag" for previously build image so that inline cache uses only remote image
      * constructs docker-compose command to run based on parameters passed
      * run the build command
      * update cached information that the build completed and saves checksums of all files
        for quick future check if the build is needed

    :param verbose: print commands when running
    :param dry_run: do not execute "write" commands - just print what would happen
    :param kwargs: arguments passed from the command
    """
    fix_group_permissions()
    parameters_passed = filter_out_none(**kwargs)
    ci_image_params = get_ci_image_build_params(parameters_passed)
    ci_image_params.print_info()
    run_command(
        [
            "docker", "rmi", "--no-prune", "--force",
            ci_image_params.airflow_image_name
        ],
        verbose=verbose,
        dry_run=dry_run,
        cwd=AIRFLOW_SOURCES_ROOT,
        text=True,
        check=False,
    )
    cmd = construct_build_docker_command(
        image_params=ci_image_params,
        verbose=verbose,
        required_args=REQUIRED_CI_IMAGE_ARGS,
        optional_args=OPTIONAL_CI_IMAGE_ARGS,
        production_image=False,
    )
    if ci_image_params.prepare_buildx_cache:
        login_to_docker_registry(ci_image_params)
    console.print(
        f"\n[blue]Building CI Image for Python {ci_image_params.python}\n")
    run_command(cmd,
                verbose=verbose,
                dry_run=dry_run,
                cwd=AIRFLOW_SOURCES_ROOT,
                text=True)
    if not dry_run:
        ci_image_cache_dir = BUILD_CACHE_DIR / ci_image_params.airflow_branch
        ci_image_cache_dir.mkdir(parents=True, exist_ok=True)
        touch_cache_file(f"built_{ci_image_params.python}",
                         root_dir=ci_image_cache_dir)
        calculate_md5_checksum_for_files(ci_image_params.md5sum_cache_dir,
                                         update=True)
    else:
        console.print(
            "[blue]Not updating build cache because we are in `dry_run` mode.[/]"
        )
예제 #2
0
def change_config(
    python: str,
    backend: str,
    postgres_version: str,
    mysql_version: str,
    mssql_version: str,
    cheatsheet: bool,
    asciiart: bool,
):
    """
    Show/update configuration (Python, Backend, Cheatsheet, ASCIIART).
    """
    asciiart_file = "suppress_asciiart"
    cheatsheet_file = "suppress_cheatsheet"

    if asciiart is not None:
        if asciiart:
            delete_cache(asciiart_file)
            console.print('[bright_blue]Enable ASCIIART![/]')
        else:
            touch_cache_file(asciiart_file)
            console.print('[bright_blue]Disable ASCIIART![/]')
    if cheatsheet is not None:
        if cheatsheet:
            delete_cache(cheatsheet_file)
            console.print('[bright_blue]Enable Cheatsheet[/]')
        elif cheatsheet is not None:
            touch_cache_file(cheatsheet_file)
            console.print('[bright_blue]Disable Cheatsheet[/]')

    def get_status(file: str):
        return "disabled" if check_if_cache_exists(file) else "enabled"

    console.print()
    console.print("[bright_blue]Current configuration:[/]")
    console.print()
    console.print(f"[bright_blue]* Python: {python}[/]")
    console.print(f"[bright_blue]* Backend: {backend}[/]")
    console.print()
    console.print(f"[bright_blue]* Postgres version: {postgres_version}[/]")
    console.print(f"[bright_blue]* MySQL version: {mysql_version}[/]")
    console.print(f"[bright_blue]* MsSQL version: {mssql_version}[/]")
    console.print()
    console.print(f"[bright_blue]* ASCIIART: {get_status(asciiart_file)}[/]")
    console.print(
        f"[bright_blue]* Cheatsheet: {get_status(cheatsheet_file)}[/]")
    console.print()
예제 #3
0
def change_config(python, backend, cheatsheet, asciiart):
    """
    Show/update configuration (Python, Backend, Cheatsheet, ASCIIART).
    """
    asciiart_file = "suppress_asciiart"
    cheatsheet_file = "suppress_cheatsheet"
    python_file = 'PYTHON_MAJOR_MINOR_VERSION'
    backend_file = 'BACKEND'
    if asciiart is not None:
        if asciiart:
            delete_cache(asciiart_file)
            console.print('[bright_blue]Enable ASCIIART![/]')
        else:
            touch_cache_file(asciiart_file)
            console.print('[bright_blue]Disable ASCIIART![/]')
    if cheatsheet is not None:
        if cheatsheet:
            delete_cache(cheatsheet_file)
            console.print('[bright_blue]Enable Cheatsheet[/]')
        elif cheatsheet is not None:
            touch_cache_file(cheatsheet_file)
            console.print('[bright_blue]Disable Cheatsheet[/]')
    if python is not None:
        write_to_cache_file(python_file, python)
        console.print(f'[bright_blue]Python default value set to: {python}[/]')
    if backend is not None:
        write_to_cache_file(backend_file, backend)
        console.print(
            f'[bright_blue]Backend default value set to: {backend}[/]')

    def get_status(file: str):
        return "disabled" if check_if_cache_exists(file) else "enabled"

    console.print()
    console.print("[bright_blue]Current configuration:[/]")
    console.print()
    console.print(
        f"[bright_blue]* Python: {read_from_cache_file(python_file)}[/]")
    console.print(
        f"[bright_blue]* Backend: {read_from_cache_file(backend_file)}[/]")
    console.print(f"[bright_blue]* ASCIIART: {get_status(asciiart_file)}[/]")
    console.print(
        f"[bright_blue]* Cheatsheet: {get_status(cheatsheet_file)}[/]")
    console.print()
예제 #4
0
def change_config(python, backend, cheatsheet, asciiart):
    """
    Toggles on/off cheatsheet, asciiart. Sets default Python and backend.
    """
    if asciiart:
        console.print('[bright_blue] ASCIIART enabled')
        delete_cache('suppress_asciiart')
    elif asciiart is not None:
        touch_cache_file('suppress_asciiart')
    else:
        pass
    if cheatsheet:
        console.print('[bright_blue] Cheatsheet enabled')
        delete_cache('suppress_cheatsheet')
    elif cheatsheet is not None:
        touch_cache_file('suppress_cheatsheet')
    else:
        pass
    if python is not None:
        write_to_cache_file('PYTHON_MAJOR_MINOR_VERSION', python)
        console.print(f'[bright_blue]Python cached_value {python}')
    if backend is not None:
        write_to_cache_file('BACKEND', backend)
        console.print(f'[bright_blue]Backend cached_value {backend}')
예제 #5
0
def build_ci_image(verbose: bool, dry_run: bool, with_ci_group: bool,
                   ci_image_params: BuildCiParams) -> Tuple[int, str]:
    """
    Builds CI image:

      * fixes group permissions for files (to improve caching when umask is 002)
      * converts all the parameters received via kwargs into BuildCIParams (including cache)
      * prints info about the image to build
      * logs int to docker registry on CI if build cache is being executed
      * removes "tag" for previously build image so that inline cache uses only remote image
      * constructs docker-compose command to run based on parameters passed
      * run the build command
      * update cached information that the build completed and saves checksums of all files
        for quick future check if the build is needed

    :param verbose: print commands when running
    :param dry_run: do not execute "write" commands - just print what would happen
    :param with_ci_group: whether to wrap the build in CI logging group
    :param ci_image_params: CI image parameters
    """
    fix_group_permissions()
    if verbose or dry_run:
        console.print(
            f"\n[bright_blue]Building CI image of airflow from {AIRFLOW_SOURCES_ROOT} "
            f"python version: {ci_image_params.python}[/]\n")
    with ci_group(
            f"Build CI image for Python {ci_image_params.python} "
            f"with tag: {ci_image_params.image_tag}",
            enabled=with_ci_group,
    ):
        ci_image_params.print_info()
        if not ci_image_params.force_build and not ci_image_params.upgrade_to_newer_dependencies:
            if not should_we_run_the_build(build_ci_params=ci_image_params):
                return 0, f"Image build: {ci_image_params.python}"
        run_command(
            [
                "docker", "rmi", "--no-prune", "--force",
                ci_image_params.airflow_image_name
            ],
            verbose=verbose,
            dry_run=dry_run,
            cwd=AIRFLOW_SOURCES_ROOT,
            text=True,
            check=False,
        )
        if ci_image_params.prepare_buildx_cache:
            login_to_docker_registry(ci_image_params, dry_run=dry_run)
        cmd = construct_docker_build_command(
            image_params=ci_image_params,
            verbose=verbose,
            required_args=REQUIRED_CI_IMAGE_ARGS,
            optional_args=OPTIONAL_CI_IMAGE_ARGS,
            production_image=False,
        )
        if ci_image_params.empty_image:
            console.print(
                f"\n[blue]Building empty CI Image for Python {ci_image_params.python}\n"
            )
            cmd = construct_empty_docker_build_command(
                image_params=ci_image_params)
            build_result = run_command(
                cmd,
                input="FROM scratch\n",
                verbose=verbose,
                dry_run=dry_run,
                cwd=AIRFLOW_SOURCES_ROOT,
                text=True,
            )
        else:
            console.print(
                f"\n[blue]Building CI Image for Python {ci_image_params.python}\n"
            )
            build_result = run_command(cmd,
                                       verbose=verbose,
                                       dry_run=dry_run,
                                       cwd=AIRFLOW_SOURCES_ROOT,
                                       text=True,
                                       check=False)
        if not dry_run:
            if build_result.returncode == 0:
                ci_image_cache_dir = BUILD_CACHE_DIR / ci_image_params.airflow_branch
                ci_image_cache_dir.mkdir(parents=True, exist_ok=True)
                touch_cache_file(f"built_{ci_image_params.python}",
                                 root_dir=ci_image_cache_dir)
                calculate_md5_checksum_for_files(
                    ci_image_params.md5sum_cache_dir, update=True)
            else:
                console.print("[red]Error when building image![/]")
                return (
                    build_result.returncode,
                    f"Image build: {ci_image_params.python}",
                )
        else:
            console.print(
                "[blue]Not updating build cache because we are in `dry_run` mode.[/]"
            )
        if ci_image_params.push_image:
            return tag_and_push_image(image_params=ci_image_params,
                                      dry_run=dry_run,
                                      verbose=verbose)
        return build_result.returncode, f"Image build: {ci_image_params.python}"