Skip to content

Commit

Permalink
feat: Support running the docker inspector on windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
taikuukaits committed Apr 15, 2020
1 parent f651469 commit 4ffc02a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.synopsys.integration.detectable.detectables.docker;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.synopsys.integration.detectable.detectable.executable.Executable;
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunner;
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunnerException;
import com.synopsys.integration.detectable.detectable.file.FileFinder;

public class BashDockerRunner {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

private final FileFinder fileFinder;
private final ExecutableRunner executableRunner;

public BashDockerRunner(final FileFinder fileFinder, final ExecutableRunner executableRunner) {
this.fileFinder = fileFinder;
this.executableRunner = executableRunner;
}

private void importTars(final List<File> importTars, final File directory, final Map<String, String> environmentVariables, final File bashExe) {
try {
for (final File imageToImport : importTars) {
final String arguments = "load -i \"" + imageToImport.getCanonicalPath() + "\"";
final Executable dockerImportImageExecutable;
if (bashExe == null) {
dockerImportImageExecutable = new Executable(directory, environmentVariables, "docker", Collections.singletonList(arguments));
} else {
// The -c is a bash option, the following String is the command we want to run
List<String> bashArguments = Arrays.asList("-c", "docker", arguments);
dockerImportImageExecutable = new Executable(directory, environmentVariables, bashExe.toString(), bashArguments);
}
executableRunner.execute(dockerImportImageExecutable);
}
} catch (final Exception e) {
logger.debug("Exception encountered when resolving paths for docker air gap, running in online mode instead");
logger.debug(e.getMessage());
}
}

public void executeDocker(final File outputDirectory, final String imageArgument, final File javaExe, final File bashExe,
final DockerInspectorInfo dockerInspectorInfo, DockerProperties dockerProperties)
throws IOException, ExecutableRunnerException {

final File dockerPropertiesFile = new File(outputDirectory, "application.properties");
dockerProperties.populatePropertiesFile(dockerPropertiesFile, outputDirectory);
final Map<String, String> environmentVariables = new HashMap<>(0);
final List<String> dockerArguments = new ArrayList<>();
dockerArguments.add("-jar");
dockerArguments.add(dockerInspectorInfo.getDockerInspectorJar().getAbsolutePath());
dockerArguments.add("--spring.config.location=file:" + dockerPropertiesFile.getCanonicalPath());
dockerArguments.add(imageArgument);
dockerArguments.add("--working.dir.path=" + outputDirectory.getAbsolutePath());
if (dockerInspectorInfo.hasAirGapImageFiles()) {
importTars(dockerInspectorInfo.getAirGapInspectorImageTarFiles(), outputDirectory, environmentVariables, bashExe);
}
final Executable dockerExecutable = new Executable(outputDirectory, environmentVariables, javaExe.getAbsolutePath(), dockerArguments);
executableRunner.execute(dockerExecutable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
import com.synopsys.integration.detectable.detectable.result.InspectorNotFoundDetectableResult;
import com.synopsys.integration.detectable.detectable.result.PassedDetectableResult;
import com.synopsys.integration.detectable.detectable.result.PropertyInsufficientDetectableResult;
import com.synopsys.integration.detectable.detectable.result.WrongOperatingSystemResult;
import com.synopsys.integration.util.OperatingSystemType;

@DetectableInfo(language = "N/A", forge = "Derived from the Linux distribution", requirementsMarkdown = "Access to a Docker Engine. See <a href='https://blackducksoftware.github.io/blackduck-docker-inspector/latest/overview/'>Docker Inspector documentation</a> for details.")
public class DockerDetectable extends Detectable {
Expand Down Expand Up @@ -71,9 +69,9 @@ public DockerDetectable(final DetectableEnvironment environment, final DockerIns

@Override
public DetectableResult applicable() {
if (OperatingSystemType.determineFromSystem() == OperatingSystemType.WINDOWS) {
return new WrongOperatingSystemResult(OperatingSystemType.determineFromSystem());
}
// if (OperatingSystemType.determineFromSystem() == OperatingSystemType.WINDOWS) {
// return new WrongOperatingSystemResult(OperatingSystemType.determineFromSystem());
// }

if (!dockerDetectableOptions.hasDockerImageOrTar()) {
return new PropertyInsufficientDetectableResult();
Expand All @@ -87,10 +85,11 @@ public DetectableResult extractable() throws DetectableException {
if (javaExe == null) {
return new ExecutableNotFoundDetectableResult("java");
}
bashExe = bashResolver.resolveBash();
if (bashExe == null) {
return new ExecutableNotFoundDetectableResult("bash");
}
//TODO: Fix - jp
// bashExe = bashResolver.resolveBash();
// if (bashExe == null) {
// return new ExecutableNotFoundDetectableResult("bash");
// }
File dockerExe;
try {
dockerExe = dockerResolver.resolveDocker();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -51,9 +46,7 @@
import com.synopsys.integration.detectable.Extraction;
import com.synopsys.integration.detectable.ExtractionMetadata;
import com.synopsys.integration.detectable.detectable.codelocation.CodeLocation;
import com.synopsys.integration.detectable.detectable.executable.Executable;
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunner;
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunnerException;
import com.synopsys.integration.detectable.detectable.file.FileFinder;
import com.synopsys.integration.detectable.detectables.docker.model.DockerImageInfo;

Expand All @@ -74,22 +67,24 @@ public class DockerExtractor {
private final BdioTransformer bdioTransformer;
private final ExternalIdFactory externalIdFactory;
private final Gson gson;
private final BashDockerRunner bashDockerRunner;

private ImageIdentifierType imageIdentifierType;

public DockerExtractor(final FileFinder fileFinder, final ExecutableRunner executableRunner, final BdioTransformer bdioTransformer, final ExternalIdFactory externalIdFactory, final Gson gson) {
public DockerExtractor(final FileFinder fileFinder, final ExecutableRunner executableRunner, final BdioTransformer bdioTransformer, final ExternalIdFactory externalIdFactory, final Gson gson,
final BashDockerRunner bashDockerRunner) {
this.fileFinder = fileFinder;
this.executableRunner = executableRunner;
this.bdioTransformer = bdioTransformer;
this.externalIdFactory = externalIdFactory;
this.gson = gson;
this.bashDockerRunner = bashDockerRunner;
}

public Extraction extract(final File directory, final File outputDirectory, final File bashExe, final File javaExe, final String image, final String imageId, final String tar, final DockerInspectorInfo dockerInspectorInfo,
DockerProperties dockerProperties) {
try {
String imageArgument = null;
String imagePiece = null;
ImageIdentifierType imageIdentifierType = null;
if (StringUtils.isNotBlank(tar)) {
final File dockerTarFile = new File(tar);
imageArgument = String.format("--docker.tar=%s", dockerTarFile.getCanonicalPath());
Expand All @@ -108,72 +103,38 @@ public Extraction extract(final File directory, final File outputDirectory, fina
if (StringUtils.isBlank(imageArgument) || StringUtils.isBlank(imagePiece)) {
return new Extraction.Builder().failure("No docker image found.").build();
} else {
return executeDocker(outputDirectory, imageArgument, imagePiece, tar, directory, javaExe, bashExe, dockerInspectorInfo, dockerProperties);
bashDockerRunner.executeDocker(outputDirectory, imageArgument, javaExe, bashExe, dockerInspectorInfo, dockerProperties);
File scanFile = findScanFile(outputDirectory, tar);
final Extraction.Builder extractionBuilder = findCodeLocations(outputDirectory, directory);
final String imageIdentifier = getImageIdentifierFromOutputDirectoryIfImageIdPresent(outputDirectory, imagePiece, imageIdentifierType);
extractionBuilder.metaData(DOCKER_TAR_META_DATA, scanFile).metaData(DOCKER_IMAGE_NAME_META_DATA, imageIdentifier);
return extractionBuilder.build();
}
} catch (final Exception e) {
return new Extraction.Builder().exception(e).build();
}
}

private void importTars(final List<File> importTars, final File directory, final Map<String, String> environmentVariables, final File bashExe) {
try {
for (final File imageToImport : importTars) {
// The -c is a bash option, the following String is the command we want to run
final List<String> dockerImportArguments = Arrays.asList(
"-c",
"docker load -i \"" + imageToImport.getCanonicalPath() + "\"");

final Executable dockerImportImageExecutable = new Executable(directory, environmentVariables, bashExe.toString(), dockerImportArguments);
executableRunner.execute(dockerImportImageExecutable);
}
} catch (final Exception e) {
logger.debug("Exception encountered when resolving paths for docker air gap, running in online mode instead");
logger.debug(e.getMessage());
}
}

private Extraction executeDocker(final File outputDirectory, final String imageArgument, final String suppliedImagePiece, final String dockerTarFilePath, final File directory, final File javaExe, final File bashExe,
final DockerInspectorInfo dockerInspectorInfo, DockerProperties dockerProperties)
throws IOException, ExecutableRunnerException {

final File dockerPropertiesFile = new File(outputDirectory, "application.properties");
dockerProperties.populatePropertiesFile(dockerPropertiesFile, outputDirectory);
final Map<String, String> environmentVariables = new HashMap<>(0);
final List<String> dockerArguments = new ArrayList<>();
dockerArguments.add("-jar");
dockerArguments.add(dockerInspectorInfo.getDockerInspectorJar().getAbsolutePath());
dockerArguments.add("--spring.config.location=file:" + dockerPropertiesFile.getCanonicalPath());
dockerArguments.add(imageArgument);
if (dockerInspectorInfo.hasAirGapImageFiles()) {
importTars(dockerInspectorInfo.getAirGapInspectorImageTarFiles(), outputDirectory, environmentVariables, bashExe);
}
final Executable dockerExecutable = new Executable(outputDirectory, environmentVariables, javaExe.getAbsolutePath(), dockerArguments);
executableRunner.execute(dockerExecutable);

File scanFile = null;
private File findScanFile(File outputDirectory, String dockerTarFilePath) throws IOException {
final File producedSquashedImageFile = fileFinder.findFile(outputDirectory, SQUASHED_IMAGE_FILENAME_PATTERN);
final File producedContainerFileSystemFile = fileFinder.findFile(outputDirectory, CONTAINER_FILESYSTEM_FILENAME_PATTERN);
if (null != producedSquashedImageFile && producedSquashedImageFile.isFile()) {
logger.debug(String.format("Will signature scan: %s", producedSquashedImageFile.getAbsolutePath()));
scanFile = producedSquashedImageFile;
return producedSquashedImageFile;
} else if (null != producedContainerFileSystemFile && producedContainerFileSystemFile.isFile()) {
logger.debug(String.format("Will signature scan: %s", producedContainerFileSystemFile.getAbsolutePath()));
scanFile = producedContainerFileSystemFile;
return producedContainerFileSystemFile;
} else {
logger.debug(String.format("No files found matching pattern [%s]. Expected docker-inspector to produce file in %s", CONTAINER_FILESYSTEM_FILENAME_PATTERN, outputDirectory.getCanonicalPath()));
if (StringUtils.isNotBlank(dockerTarFilePath)) {
final File dockerTarFile = new File(dockerTarFilePath);
if (dockerTarFile.isFile()) {
logger.debug(String.format("Will scan the provided Docker tar file %s", dockerTarFile.getCanonicalPath()));
scanFile = dockerTarFile;
return dockerTarFile;
}
}
}

final Extraction.Builder extractionBuilder = findCodeLocations(outputDirectory, directory);
final String imageIdentifier = getImageIdentifierFromOutputDirectoryIfImageIdPresent(outputDirectory, suppliedImagePiece, imageIdentifierType);
extractionBuilder.metaData(DOCKER_TAR_META_DATA, scanFile).metaData(DOCKER_IMAGE_NAME_META_DATA, imageIdentifier);
return extractionBuilder.build();
return null;
}

private Extraction.Builder findCodeLocations(final File directoryToSearch, final File directory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import com.synopsys.integration.detectable.detectables.cran.PackratLockExtractor;
import com.synopsys.integration.detectable.detectables.cran.parse.PackratDescriptionFileParser;
import com.synopsys.integration.detectable.detectables.cran.parse.PackratLockFileParser;
import com.synopsys.integration.detectable.detectables.docker.BashDockerRunner;
import com.synopsys.integration.detectable.detectables.docker.DockerDetectable;
import com.synopsys.integration.detectable.detectables.docker.DockerDetectableOptions;
import com.synopsys.integration.detectable.detectables.docker.DockerExtractor;
Expand Down Expand Up @@ -652,8 +653,12 @@ private GradleInspectorExtractor gradleInspectorExtractor() {
return new GradleInspectorExtractor(executableRunner, fileFinder, gradleReportParser(), gradleReportTransformer(), gradleRootMetadataParser());
}

private BashDockerRunner bashDockerRunner() {
return new BashDockerRunner(fileFinder, executableRunner);
}

private DockerExtractor dockerExtractor() {
return new DockerExtractor(fileFinder, executableRunner, new BdioTransformer(), new ExternalIdFactory(), gson);
return new DockerExtractor(fileFinder, executableRunner, new BdioTransformer(), new ExternalIdFactory(), gson, bashDockerRunner());
}

private GemspecLineParser gemspecLineParser() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunner;
import com.synopsys.integration.detectable.detectable.executable.ExecutableRunnerException;
import com.synopsys.integration.detectable.detectable.file.FileFinder;
import com.synopsys.integration.detectable.detectables.docker.BashDockerRunner;
import com.synopsys.integration.detectable.detectables.docker.DockerExtractor;
import com.synopsys.integration.detectable.detectables.docker.DockerInspectorInfo;
import com.synopsys.integration.detectable.detectables.docker.DockerProperties;
Expand Down Expand Up @@ -204,7 +205,7 @@ private DockerExtractor getMockDockerExtractor(ExecutableRunner executableRunner
final ExternalIdFactory externalIdFactory = Mockito.mock(ExternalIdFactory.class);
final Gson gson = new Gson();

return new DockerExtractor(fileFinder, executableRunner, bdioTransformer, externalIdFactory, gson);
return new DockerExtractor(fileFinder, executableRunner, bdioTransformer, externalIdFactory, gson, new BashDockerRunner(fileFinder, executableRunner));
}

private Extraction extract(final String image, final String imageId, final String tar,
Expand Down

0 comments on commit 4ffc02a

Please sign in to comment.