Java tutorial
/** * Hub Docker Inspector * * Copyright (C) 2017 Black Duck Software, Inc. * http://www.blackducksoftware.com/ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.blackducksoftware.integration.hub.docker; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.blackducksoftware.integration.exception.IntegrationException; import com.blackducksoftware.integration.hub.bdio.simple.BdioWriter; import com.blackducksoftware.integration.hub.docker.client.DockerClientManager; import com.blackducksoftware.integration.hub.docker.client.ProgramPaths; import com.blackducksoftware.integration.hub.docker.dependencynode.DependencyNodeWriter; import com.blackducksoftware.integration.hub.docker.extractor.ExtractionDetails; import com.blackducksoftware.integration.hub.docker.extractor.Extractor; import com.blackducksoftware.integration.hub.docker.linux.EtcDir; import com.blackducksoftware.integration.hub.docker.linux.FileOperations; import com.blackducksoftware.integration.hub.docker.tar.DockerTarParser; import com.blackducksoftware.integration.hub.docker.tar.ImageInfo; import com.blackducksoftware.integration.hub.docker.tar.manifest.ManifestLayerMapping; import com.blackducksoftware.integration.hub.exception.HubIntegrationException; import com.google.gson.Gson; @Component public class HubDockerManager { private final Logger logger = LoggerFactory.getLogger(HubDockerManager.class); @Value("${linux.distro}") private String linuxDistro; @Autowired private HubClient hubClient; @Autowired private ProgramPaths programPaths; @Autowired private DockerClientManager dockerClientManager; @Autowired private List<Extractor> extractors; @Autowired private DockerTarParser tarParser; public void init() { tarParser.setWorkingDirectory(new File(programPaths.getHubDockerWorkingDirPath())); } public File getTarFileFromDockerImage(final String imageName, final String tagName) throws IOException { return dockerClientManager.getTarFileFromDockerImage(imageName, tagName); } public List<File> extractLayerTars(final File dockerTar) throws IOException { return tarParser.extractLayerTars(dockerTar); } public File extractDockerLayers(final List<File> layerTars, final List<ManifestLayerMapping> layerMappings) throws IOException { return tarParser.extractDockerLayers(layerTars, layerMappings); } public OperatingSystemEnum detectOperatingSystem(final String operatingSystem, final File targetImageFileSystemRootDir) throws HubIntegrationException, IOException { return tarParser.detectOperatingSystem(operatingSystem, targetImageFileSystemRootDir); } public OperatingSystemEnum detectCurrentOperatingSystem() throws HubIntegrationException, IOException { final EtcDir etcDir = new EtcDir(new File("/etc")); return etcDir.getOperatingSystem(); } public List<ManifestLayerMapping> getLayerMappings(final String tarFileName, final String dockerImageName, final String dockerTagName) throws Exception { return tarParser.getLayerMappings(tarFileName, dockerImageName, dockerTagName); } public List<File> generateBdioFromImageFilesDir(final String dockerImageRepo, final String dockerImageTag, final List<ManifestLayerMapping> mappings, final String projectName, final String versionName, final File dockerTar, final File targetImageFileSystemRootDir, final OperatingSystemEnum osEnum) throws IOException, HubIntegrationException, InterruptedException { final ImageInfo imagePkgMgrInfo = tarParser.collectPkgMgrInfo(targetImageFileSystemRootDir, osEnum); if (imagePkgMgrInfo.getOperatingSystemEnum() == null) { throw new HubIntegrationException("Could not determine the Operating System of this Docker tar."); } String architecture = null; if (osEnum == OperatingSystemEnum.ALPINE) { // TODO This code should be in a pkg-manager-specific class final List<File> etcDirectories = FileOperations.findFileWithName(targetImageFileSystemRootDir, "etc"); for (final File etc : etcDirectories) { File architectureFile = new File(etc, "apk"); architectureFile = new File(architectureFile, "arch"); if (architectureFile.exists()) { architecture = FileUtils.readLines(architectureFile, "UTF-8").get(0); break; } } } logger.debug(String.format("generateBdioFromImageFilesDir(): architecture: %s", architecture)); return generateBdioFromPackageMgrDirs(dockerImageRepo, dockerImageTag, mappings, projectName, versionName, dockerTar.getName(), imagePkgMgrInfo, architecture); } public void uploadBdioFiles(final List<File> bdioFiles) throws IntegrationException { if (hubClient.isValid()) { if (bdioFiles != null) { for (final File file : bdioFiles) { hubClient.uploadBdioToHub(file); } } logger.info(" "); logger.info("Successfully uploaded all of the bdio files!"); logger.info(" "); } } public void cleanWorkingDirectory() throws IOException { final File workingDirectory = new File(programPaths.getHubDockerWorkingDirPath()); if (workingDirectory.exists()) { FileUtils.deleteDirectory(workingDirectory); } } private List<File> generateBdioFromPackageMgrDirs(final String dockerImageRepo, final String dockerImageTag, final List<ManifestLayerMapping> layerMappings, final String projectName, final String versionName, final String tarFileName, final ImageInfo imageInfo, final String architecture) throws FileNotFoundException, IOException, HubIntegrationException, InterruptedException { final File outputDirectory = new File(programPaths.getHubDockerOutputPath()); final List<File> bdioFiles = new ArrayList<>(); ManifestLayerMapping manifestMapping = null; for (final ManifestLayerMapping mapping : layerMappings) { if (StringUtils.compare(mapping.getTargetImageFileSystemRootDirName(), imageInfo.getFileSystemRootDirName()) == 0) { manifestMapping = mapping; } } if (manifestMapping == null) { throw new HubIntegrationException( String.format("Mapping for %s not found in target image manifest file", imageInfo.getFileSystemRootDirName())); } String codeLocationName, hubProjectName, hubVersionName = ""; final String imageDirectoryName = manifestMapping.getTargetImageFileSystemRootDirName(); String pkgMgrFilePath = imageInfo.getPkgMgr().getExtractedPackageManagerDirectory().getAbsolutePath(); pkgMgrFilePath = pkgMgrFilePath .substring(pkgMgrFilePath.indexOf(imageDirectoryName) + imageDirectoryName.length() + 1); codeLocationName = programPaths.getCodeLocationName(manifestMapping.getImageName(), manifestMapping.getTagName(), pkgMgrFilePath, imageInfo.getPkgMgr().getPackageManager().toString()); hubProjectName = deriveHubProject(manifestMapping.getImageName(), projectName); hubVersionName = deriveHubProjectVersion(manifestMapping, versionName); logger.info(String.format("Hub project, version: %s, %s; Code location : %s", hubProjectName, hubVersionName, codeLocationName)); final String bdioFilename = programPaths.getBdioFilename(manifestMapping.getImageName(), pkgMgrFilePath, hubProjectName, hubVersionName); final String dependenciesFilename = programPaths.getDependencyNodesFilename(manifestMapping.getImageName(), pkgMgrFilePath, hubProjectName, hubVersionName); logger.debug( String.format("bdioFilename: %s; dependenciesFilename: %s", bdioFilename, dependenciesFilename)); final File bdioOutputFile = new File(outputDirectory, bdioFilename); final File dependenciesOutputFile = new File(outputDirectory, dependenciesFilename); logger.trace(String.format("dependenciesOutputFile: %s", dependenciesOutputFile)); bdioFiles.add(bdioOutputFile); try (FileOutputStream bdioOutputStream = new FileOutputStream(bdioOutputFile); FileOutputStream dependenciesOutputStream = new FileOutputStream(dependenciesOutputFile)) { try (BdioWriter bdioWriter = new BdioWriter(new Gson(), bdioOutputStream); DependencyNodeWriter dependenciesWriter = new DependencyNodeWriter(new Gson(), dependenciesOutputStream)) { final Extractor extractor = getExtractorByPackageManager(imageInfo.getPkgMgr().getPackageManager()); final ExtractionDetails extractionDetails = new ExtractionDetails( imageInfo.getOperatingSystemEnum(), architecture); extractor.extract(dockerImageRepo, dockerImageTag, imageInfo.getPkgMgr(), bdioWriter, dependenciesWriter, extractionDetails, codeLocationName, hubProjectName, hubVersionName); } } return bdioFiles; } private String deriveHubProject(final String imageName, final String projectName) { String hubProjectName; if (StringUtils.isBlank(projectName)) { hubProjectName = programPaths.cleanImageName(imageName); } else { logger.debug("Using project from config property"); hubProjectName = projectName; } return hubProjectName; } private String deriveHubProjectVersion(final ManifestLayerMapping mapping, final String versionName) { String hubVersionName; if (StringUtils.isBlank(versionName)) { hubVersionName = mapping.getTagName(); } else { logger.debug("Using project version from config property"); hubVersionName = versionName; } return hubVersionName; } private Extractor getExtractorByPackageManager(final PackageManagerEnum packageManagerEnum) throws HubIntegrationException { for (final Extractor currentExtractor : extractors) { if (currentExtractor.getPackageManagerEnum() == packageManagerEnum) { return currentExtractor; } } throw new HubIntegrationException( String.format("Extractor not found for packageManager %s", packageManagerEnum.toString())); } }