def docker_rmi(user, tag, component): # noqa: D301 """Remove REANA component images. \b :param components: The option ``component`` can be repeated. The value may consist of: * (1) standard component name such as 'reana-workflow-controller'; * (2) short component name such as 'r-w-controller'; * (3) special value '.' indicating component of the current working directory; * (4) special value 'CLUSTER' that will expand to cover all REANA cluster components [default]; * (5) special value 'CLIENT' that will expand to cover all REANA client components; * (6) special value 'DEMO' that will expand to include several runable REANA demo examples; * (7) special value 'ALL' that will expand to include all REANA repositories. :param user: DockerHub organisation or user name. [default=reanahub] :param tag: Docker tag to use. [default=latest] :type component: str :type user: str :type tag: str """ components = select_components(component) for component in components: if is_component_dockerised(component): cmd = "docker rmi {0}/{1}:{2}".format(user, component, tag) run_command(cmd, component) else: msg = "Ignoring this component that does not contain" " a Dockerfile." display_message(msg, component)
def helm_upgrade_components(ctx, user, push): # noqa: D301 """Upgrade REANA Helm dependencies.""" def _update_values_yaml(new_docker_images): """Update all images in ``values.yaml``, skipping the ones up to date.""" values_yaml_relative_path = "helm/reana/values.yaml" values_yaml_abs_path = os.path.join( get_srcdir("reana"), values_yaml_relative_path ) values_yaml = "" with open(values_yaml_abs_path) as f: values_yaml = f.read() for docker_image in new_docker_images: image_name, _ = docker_image.split(":") if image_name in values_yaml: values_yaml = re.sub( f"{image_name}:.*", lambda _: docker_image, values_yaml, count=1 ) with open(values_yaml_abs_path, "w") as f: f.write(values_yaml) display_message( f"{values_yaml_relative_path} successfully updated.", component="reana" ) remaining_docker_releases = [] new_docker_images = [] for component in REPO_LIST_CLUSTER: if not is_component_dockerised(component): continue if not git_is_current_version_tagged(component): remaining_docker_releases.append(component) else: new_docker_images.append(f"{user}/{component}:{get_docker_tag(component)}") if remaining_docker_releases: line_by_line_missing_releases = "\n".join(remaining_docker_releases) click.secho( "The following components are missing to be released:\n" f"{line_by_line_missing_releases}", fg="red", ) sys.exit(1) _update_values_yaml(new_docker_images) ctx.invoke(git_diff, component=["reana"]) if push: git_push_to_origin(["reana"])
def _get_docker_releases(dockerhub_user: str) -> List[str]: """Return released docker images (name + tag) of all components. Iterate over the components that provide Docker image and have a current version os source code tagged, extract docker images and return as a list """ docker_images = [] for component in REPO_LIST_CLUSTER: if is_component_dockerised(component) and git_is_current_version_tagged( component ): docker_images.append( f"{dockerhub_user}/{component}:{get_docker_tag(component)}" ) return docker_images
def release_docker(ctx, component, user, image_name): # noqa: D301 """Release a component on Docker Hub. \b :param components: The option ``component`` can be repeated. The value may consist of: * (1) standard component name such as 'reana-workflow-controller'; * (2) short component name such as 'r-w-controller'; * (3) special value '.' indicating component of the current working directory; * (4) special value 'CLUSTER' that will expand to cover all REANA cluster components [default]; * (5) special value 'CLIENT' that will expand to cover all REANA client components; * (6) special value 'DEMO' that will expand to include several runable REANA demo examples; * (7) special value 'ALL' that will expand to include all REANA repositories. :type component: str """ components = select_components(component) cannot_release_on_dockerhub = [] for component_ in components: if not is_component_dockerised(component_): cannot_release_on_dockerhub.append(component_) is_component_releasable(component_, exit_code=True, display=True) full_image_name = f"{user}/{image_name or component_}" docker_tag = get_docker_tag(component_) run_command( f"docker tag {full_image_name}:latest {full_image_name}:{docker_tag}", component_, ) ctx.invoke(docker_push, component=[component_], tag=docker_tag, user=user) if cannot_release_on_dockerhub: click.secho( "The following components are not releasable on DockerHub: " f"{', '.join(cannot_release_on_dockerhub)}", fg="red", ) sys.exit(1)
def kind_load_docker_image(user, component, node, exclude_components): # noqa: D301 """Load Docker images to the cluster. \b :param user: DockerHub organisation or user name. [default=reanahub] :param components: The option ``component`` can be repeated. The value may consist of: * (1) standard component name such as 'reana-workflow-controller'; * (2) short component name such as 'r-w-controller'; * (3) special value '.' indicating component of the current working directory; * (4) special value 'CLUSTER' that will expand to cover all REANA cluster components [default]; * (5) special value 'CLIENT' that will expand to cover all REANA client components; * (6) special value 'DEMO' that will expand to include several runable REANA demo examples; * (7) special value 'ALL' that will expand to include all REANA repositories. :param exclude_components: List of components to exclude from the build. :type user: str :type component: str :type exclude_components: str """ if exclude_components: exclude_components = exclude_components.split(",") for component in select_components(component, exclude_components): if component in DOCKER_PREFETCH_IMAGES: for image in DOCKER_PREFETCH_IMAGES[component]: cmd = "kind load docker-image {0}".format(image) if node: cmd = f"{cmd} --nodes {','.join(node)}" run_command(cmd, component) elif is_component_dockerised(component): cmd = "kind load docker-image {0}/{1}".format(user, component) if node: cmd = f"{cmd} --nodes {','.join(node)}" run_command(cmd, component) else: msg = "Ignoring this component that does not contain" " a Dockerfile." display_message(msg, component)
def _check_if_missing_docker_releases() -> None: """Check if all dockerised components are released. If not, print those components and exit with status 1. """ remaining_docker_releases = [] for component in REPO_LIST_CLUSTER: if not is_component_dockerised(component): continue if not git_is_current_version_tagged(component): remaining_docker_releases.append(component) if remaining_docker_releases: line_by_line_missing_releases = "\n".join(remaining_docker_releases) click.secho( "The following components are missing to be released:\n" f"{line_by_line_missing_releases}", fg="red", ) sys.exit(1)
def docker_build( ctx, user, tag, component, build_arg, no_cache, output_component_versions, quiet, exclude_components, ): # noqa: D301 """Build REANA component images. \b :param components: The option ``component`` can be repeated. The value may consist of: * (1) standard component name such as 'reana-workflow-controller'; * (2) short component name such as 'r-w-controller'; * (3) special value '.' indicating component of the current working directory; * (4) special value 'CLUSTER' that will expand to cover all REANA cluster components [default]; * (5) special value 'CLIENT' that will expand to cover all REANA client components; * (6) special value 'DEMO' that will expand to include several runable REANA demo examples; * (7) special value 'ALL' that will expand to include all REANA repositories. :param exclude_components: List of components to exclude from the build. :param user: DockerHub organisation or user name. [default=reanahub] :param tag: Docker image tag to generate. Default 'latest'. Use 'auto' to generate git-tag-based value such as '0.7.0-alpha.3'. :param build_arg: Optional docker build argument. (e.g. DEBUG=1) :param no_cache: Flag instructing to avoid using cache. [default=False] :param output_component_versions: File where to write the built images tags. Useful when using `--tag auto` since every REANA component will have a different tag. :type component: str :type exclude_components: str :type user: str :type tag: str :type build_arg: str :type no_cache: bool :type output_component_versions: File :type quiet: bool """ if exclude_components: exclude_components = exclude_components.split(",") components = select_components(component, exclude_components) built_components_versions_tags = [] for component in components: component_tag = tag if is_component_dockerised(component): cmd = "docker build" if tag == "auto": component_tag = get_docker_tag(component) for arg in build_arg: cmd += " --build-arg {0}".format(arg) if no_cache: cmd += " --no-cache" if quiet: cmd += " --quiet" component_version_tag = "{0}/{1}:{2}".format( user, component, component_tag) cmd += " -t {0} .".format(component_version_tag) run_command(cmd, component) built_components_versions_tags.append(component_version_tag) else: msg = "Ignoring this component that does not contain" " a Dockerfile." display_message(msg, component) if output_component_versions: output_component_versions.write( "\n".join(built_components_versions_tags) + "\n")
def test_is_component_dockerised(): """Tests for is_component_dockerised().""" from reana.reana_dev.utils import is_component_dockerised assert is_component_dockerised("reana") is False