Exemple #1
0
def should_we_run_the_build(build_ci_params: BuildCiParams) -> bool:
    """
    Check if we should run the build based on what files have been modified since last build and answer from
    the user.

    * If build is needed, the user is asked for confirmation
    * If the branch is not rebased it warns the user to rebase (to make sure latest remote cache is useful)
    * Builds Image/Skips/Quits depending on the answer

    :param build_ci_params: parameters for the build
    """
    # We import those locally so that click autocomplete works
    from inputimeout import TimeoutOccurred

    if not md5sum_check_if_build_is_needed(
            md5sum_cache_dir=build_ci_params.md5sum_cache_dir):
        return False
    try:
        answer = user_confirm(message="Do you want to build image?",
                              timeout=5,
                              default_answer=Answer.NO)
        if answer == answer.YES:
            if is_repo_rebased(build_ci_params.github_repository,
                               build_ci_params.airflow_branch):
                return True
            else:
                console.print(
                    "\n[bright_yellow]This might take a lot of time, w"
                    "e think you should rebase first.[/]\n")
                answer = user_confirm(
                    "But if you really, really want - you can do it",
                    timeout=5,
                    default_answer=Answer.NO)
                if answer == Answer.YES:
                    return True
                else:
                    console.print(
                        "[bright_blue]Please rebase your code before continuing.[/]\n"
                        "Check this link to know more "
                        "https://github.com/apache/airflow/blob/main/CONTRIBUTING.rst#id15\n"
                    )
                    console.print('[red]Exiting the process[/]\n')
                    sys.exit(1)
        elif answer == Answer.NO:
            instruct_build_image(build_ci_params.python)
            return False
        else:  # users_status == Answer.QUIT:
            console.print('\n[bright_yellow]Quitting the process[/]\n')
            sys.exit()
    except TimeoutOccurred:
        console.print('\nTimeout. Considering your response as No\n')
        instruct_build_image(build_ci_params.python)
        return False
    except Exception as e:
        console.print(f'\nTerminating the process on {e}')
        sys.exit(1)
Exemple #2
0
def build_image_if_needed_steps(verbose: bool, dry_run: bool, shell_params: ShellParams) -> None:
    """
    Check if image build is needed based on what files have been modified since last build.

    * If build is needed, the user is asked for confirmation
    * If the branch is not rebased it warns the user to rebase (to make sure latest remote cache is useful)
    * Builds Image/Skips/Quits depending on the answer

    :param verbose: print commands when running
    :param dry_run: do not execute "write" commands - just print what would happen
    :param shell_params: parameters for the build
    """
    # We import those locally so that click autocomplete works
    from inputimeout import TimeoutOccurred

    build_needed = md5sum_check_if_build_is_needed(shell_params.md5sum_cache_dir, shell_params.the_image_type)
    if not build_needed:
        return
    try:
        answer = user_confirm(message="Do you want to build image?", timeout=5, default_answer=Answer.NO)
        if answer == answer.YES:
            if is_repo_rebased(shell_params.github_repository, shell_params.airflow_branch):
                build_image(
                    verbose,
                    dry_run=dry_run,
                    python=shell_params.python,
                    upgrade_to_newer_dependencies="false",
                )
            else:
                console.print(
                    "\n[bright_yellow]This might take a lot of time, w"
                    "e think you should rebase first.[/]\n"
                )
                if click.confirm("But if you really, really want - you can do it"):
                    build_image(
                        verbose=verbose,
                        dry_run=dry_run,
                        python=shell_params.python,
                        upgrade_to_newer_dependencies="false",
                    )
                else:
                    console.print(
                        "[bright_blue]Please rebase your code before continuing.[/]\n"
                        "Check this link to know more "
                        "https://github.com/apache/airflow/blob/main/CONTRIBUTING.rst#id15\n"
                    )
                    console.print('[red]Exiting the process[/]\n')
                    sys.exit(1)
        elif answer == Answer.NO:
            instruct_build_image(shell_params.python)
        else:  # users_status == Answer.QUIT:
            console.print('\n[bright_yellow]Quitting the process[/]\n')
            sys.exit()
    except TimeoutOccurred:
        console.print('\nTimeout. Considering your response as No\n')
        instruct_build_image(shell_params.python)
    except Exception as e:
        console.print(f'\nTerminating the process on {e}')
        sys.exit(1)
Exemple #3
0
def ask_to_reinstall_breeze(breeze_sources: Path):
    """
    Ask the user to reinstall Breeze (and do so if confirmed).
    :param breeze_sources: breeze sources to reinstall Breeze from.
    """
    answer = user_confirm(
        f"Do you want to reinstall Breeze from {breeze_sources.parent.parent}?",
        timeout=3,
        default_answer=Answer.NO,
    )
    if answer == Answer.YES:
        reinstall_breeze(breeze_sources)
    elif answer == Answer.QUIT:
        sys.exit(1)
Exemple #4
0
def free_space(verbose: bool, dry_run: bool, answer: str):
    set_forced_answer(answer)
    if user_confirm("Are you sure to run free-space and perform cleanup?",
                    timeout=None) == Answer.YES:
        run_command(["sudo", "swapoff", "-a"],
                    verbose=verbose,
                    dry_run=dry_run)
        run_command(["sudo", "rm", "-f", "/swapfile"],
                    verbose=verbose,
                    dry_run=dry_run)
        run_command(["sudo", "apt-get", "clean"],
                    verbose=verbose,
                    dry_run=dry_run,
                    check=False)
        run_command(
            ["docker", "system", "prune", "--all", "--force", "--volumes"],
            verbose=verbose,
            dry_run=dry_run)
        run_command(["df", "-h"], verbose=verbose, dry_run=dry_run)
        run_command(["docker", "logout", "ghcr.io"],
                    verbose=verbose,
                    dry_run=dry_run,
                    check=False)
Exemple #5
0
def cleanup(verbose: bool, dry_run: bool, also_remove_current_images: bool,
            answer: Optional[str]):
    set_forced_answer(answer)
    if also_remove_current_images:
        console.print(
            "\n[bright_yellow]Removing cache of parameters, clean up docker cache "
            "and remove locally downloaded images[/]")
    else:
        console.print(
            "\n[bright_yellow]Removing cache of parameters, and cleans up docker cache[/]"
        )
    if also_remove_current_images:
        docker_images_command_to_execute = [
            'docker',
            'images',
            '--filter',
            'label=org.apache.airflow.image',
            '--format',
            '{{.Repository}}:{{.Tag}}',
        ]
        process = run_command(docker_images_command_to_execute,
                              verbose=verbose,
                              text=True,
                              capture_output=True)
        images = process.stdout.splitlines(
        ) if process and process.stdout else []
        if images:
            console.print("[light_blue]Removing images:[/]")
            for image in images:
                console.print(f"[light_blue] * {image}[/]")
            console.print()
            docker_rmi_command_to_execute = [
                'docker',
                'rmi',
                '--force',
            ]
            docker_rmi_command_to_execute.extend(images)
            answer = user_confirm("Are you sure?", timeout=None)
            if answer == Answer.YES:
                run_command(docker_rmi_command_to_execute,
                            verbose=verbose,
                            dry_run=dry_run,
                            check=False)
            elif answer == Answer.QUIT:
                sys.exit(0)
        else:
            console.print(
                "[light_blue]No locally downloaded images to remove[/]\n")
    console.print("Pruning docker images")
    answer = user_confirm("Are you sure?", timeout=None)
    if answer == Answer.YES:
        system_prune_command_to_execute = ['docker', 'system', 'prune']
        run_command(system_prune_command_to_execute,
                    verbose=verbose,
                    dry_run=dry_run,
                    check=False)
    elif answer == Answer.QUIT:
        sys.exit(0)
    console.print(f"Removing build cache dir ${BUILD_CACHE_DIR}")
    answer = user_confirm("Are you sure?", timeout=None)
    if answer == Answer.YES:
        if not dry_run:
            shutil.rmtree(BUILD_CACHE_DIR, ignore_errors=True)
    elif answer == Answer.QUIT:
        sys.exit(0)
Exemple #6
0
def setup_autocomplete(verbose: bool, dry_run: bool, force: bool,
                       answer: Optional[str]):
    """
    Enables autocompletion of breeze commands.
    """
    set_forced_answer(answer)
    # Determine if the shell is bash/zsh/powershell. It helps to build the autocomplete path
    detected_shell = os.environ.get('SHELL')
    detected_shell = None if detected_shell is None else detected_shell.split(
        os.sep)[-1]
    if detected_shell not in ['bash', 'zsh', 'fish']:
        console.print(
            f"\n[red] The shell {detected_shell} is not supported for autocomplete![/]\n"
        )
        sys.exit(1)
    console.print(f"Installing {detected_shell} completion for local user")
    autocomplete_path = (AIRFLOW_SOURCES_ROOT / "dev" / "breeze" /
                         "autocomplete" /
                         f"{NAME}-complete-{detected_shell}.sh")
    console.print(
        f"[bright_blue]Activation command script is available here: {autocomplete_path}[/]\n"
    )
    console.print(
        f"[bright_yellow]We need to add above script to your {detected_shell} profile.[/]\n"
    )
    answer = user_confirm("Should we proceed ?",
                          default_answer=Answer.NO,
                          timeout=3)
    if answer == Answer.YES:
        if detected_shell == 'bash':
            script_path = str(Path('~').expanduser() / '.bash_completion')
            command_to_execute = f"source {autocomplete_path}"
            write_to_shell(command_to_execute, dry_run, script_path, force)
        elif detected_shell == 'zsh':
            script_path = str(Path('~').expanduser() / '.zshrc')
            command_to_execute = f"source {autocomplete_path}"
            write_to_shell(command_to_execute, dry_run, script_path, force)
        elif detected_shell == 'fish':
            # Include steps for fish shell
            script_path = str(
                Path('~').expanduser() /
                f'.config/fish/completions/{NAME}.fish')
            if os.path.exists(script_path) and not force:
                console.print(
                    "\n[bright_yellow]Autocompletion is already setup. Skipping. "
                    "You can force autocomplete installation by adding --force/]\n"
                )
            else:
                with open(autocomplete_path) as source_file, open(
                        script_path, 'w') as destination_file:
                    for line in source_file:
                        destination_file.write(line)
        else:
            # Include steps for powershell
            subprocess.check_call([
                'powershell',
                'Set-ExecutionPolicy Unrestricted -Scope CurrentUser'
            ])
            script_path = (subprocess.check_output(
                ['powershell', '-NoProfile',
                 'echo $profile']).decode("utf-8").strip())
            command_to_execute = f". {autocomplete_path}"
            write_to_shell(command_to_execute, dry_run, script_path, force)
    elif answer == Answer.NO:
        console.print(
            "\nPlease follow the https://click.palletsprojects.com/en/8.1.x/shell-completion/ "
            "to setup autocompletion for breeze manually if you want to use it.\n"
        )
    else:
        sys.exit(0)