/******************************************************************************* * Copyright (c) 2016 Red Hat. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat - Initial Contribution *******************************************************************************/ package org.eclipse.linuxtools.internal.docker.core; import java.util.List; import org.eclipse.linuxtools.docker.core.IDockerContainer; import org.eclipse.linuxtools.docker.core.IDockerImage; import org.eclipse.linuxtools.docker.core.IDockerImageHierarchyNode; /** * Utility class to resolve {@link IDockerImageHierarchyNode} */ public class DockerImageHierarchyNodeUtils { public static IDockerImageHierarchyNode resolveImageHierarchy( final List<IDockerImage> images, final List<IDockerContainer> containers, final IDockerImage image) { // recursively find all parents and build associated // IDockerImageHierarchyNode instances final IDockerImageHierarchyNode parentImageNode = getImageParentImageNode( images, image.parentId()); return getDockerImageHierarchyNode(images, containers, image, parentImageNode); } public static IDockerImageHierarchyNode resolveImageHierarchy( final List<IDockerImage> images, final IDockerContainer container) { final IDockerImageHierarchyNode parentImageNode = getContainerParentImageNode( images, container.image()); final DockerImageHierarchyNode dockerImageHierarchyNode = getDockerImageHierarchyNode( container, parentImageNode); return dockerImageHierarchyNode; } /** * Resolves the parent {@link IDockerImageHierarchyNode} for an * {@link IDockerImage}. * * @param images * all existing {@link IDockerImage} * @param parentImageId * the id of the parent {@link IDockerImage} to look-up * @return the {@link IDockerImageHierarchyNode} corresponding to the parent * {@link IDockerImage} to look-up or <code>null</code> if none was * found. */ private static IDockerImageHierarchyNode getImageParentImageNode( final List<IDockerImage> images, final String parentImageId) { // recursively find all parents and build associated // IDockerImageHierarchyNode instances return images.stream().filter(image -> image.id().equals(parentImageId)) // parent image found: get its own parent image hierarchy .map(parentImage -> new DockerImageHierarchyImageNode( parentImage, getImageParentImageNode(images, parentImage.parentId()))) .findFirst() // no parent image found: stop here. .orElse(null); } /** * Resolves the parent {@link IDockerImageHierarchyNode} for an * {@link IDockerContainer}. * * @param images * all existing {@link IDockerImage} * @param parentImageName * the name of the parent {@link IDockerImage} to look-up * @return the {@link IDockerImageHierarchyNode} corresponding to the parent * {@link IDockerImage} to look-up or <code>null</code> if none was * found. */ private static IDockerImageHierarchyNode getContainerParentImageNode( final List<IDockerImage> images, final String parentImageName) { // recursively find all parents and build associated // IDockerImageHierarchyNode instances return images.stream() .filter(image -> image.repoTags().contains(parentImageName)) // parent image found: get its own parent image hierarchy .map(parentImage -> new DockerImageHierarchyImageNode( parentImage, getImageParentImageNode(images, parentImage.parentId()))) .findFirst() // no parent image found: stop here. .orElse(null); } private static DockerImageHierarchyNode getDockerImageHierarchyNode( final List<IDockerImage> images, final List<IDockerContainer> containers, final IDockerImage image, final IDockerImageHierarchyNode parentImageNode) { final DockerImageHierarchyNode imageNode = new DockerImageHierarchyImageNode( image, parentImageNode); // also includes all children images/containers, recursively resolveChildrenImageNodes(images, containers, image.id(), image.repoTags(), imageNode); return imageNode; } private static void resolveChildrenImageNodes( final List<IDockerImage> images, final List<IDockerContainer> containers, final String imageId, final List<String> imageRepoTags, final IDockerImageHierarchyNode parentNode) { // recursively find all parents and build associated // IDockerImageHierarchyNode instances images.stream().filter(image -> image.parentId() != null && image.parentId().equals(imageId)) // use the flatMap below to duplicate images that have multiple repos //.flatMap(image -> DockerImage.duplicateImageByRepo(image)) .forEach(image -> { final DockerImageHierarchyNode childNode = new DockerImageHierarchyImageNode( image, parentNode); resolveChildrenImageNodes(images, containers, image.id(), image.repoTags(), childNode); }); containers.stream() .filter(container -> container.image() != null && imageRepoTags.contains(container.image())) .forEach(container -> new DockerImageHierarchyContainerNode( container, parentNode)); } private static DockerImageHierarchyNode getDockerImageHierarchyNode( final IDockerContainer container, final IDockerImageHierarchyNode parentImageNode) { // recursively find all parents and build associated // IDockerImageHierarchyNode instances final DockerImageHierarchyNode containerNode = new DockerImageHierarchyContainerNode( container, parentImageNode); // there's no children images/containers for a container, so let's just // return the node return containerNode; } }