Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions docs/detectors/linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,6 @@ Linux detection depends on the following:
Linux package detection is performed by running [Syft](https://github.com/anchore/syft) and parsing the output.
The output contains the package name, version, and the layer of the container in which it was found.

### Supported Input Types

The Linux detector runs on container images passed under the `--DockerImagesToScan` flag.

Supported image reference formats are:

#### Name and Tag/Digest

Images in the local Docker daemon or a remote registry can be referenced by name and tag or digest. For example, `ubuntu:16.04`. Remote images will be pulled if they are not present locally.

#### Digest Only

Images already present in the local Docker daemon can be referenced by just a digest. For example, `sha256:56bab49eef2ef07505f6a1b0d5bd3a601dfc3c76ad4460f24c91d6fa298369ab`.

#### OCI Images

Images present on the filesystem as either an [OCI layout directory](https://specs.opencontainers.org/image-spec/image-layout/) or an OCI image archive (tarball) can be referenced by file path.

- For OCI image layout directories, use the prefix `oci-dir:` followed by the path to the directory, e.g. `oci-dir:/path/to/image`
- For OCI image archives (tarballs), use the prefix `oci-archive:` followed by the path to the archive file, e.g. `oci-archive:/path/to/image.tar`

### Scanner Scope

By default, this detector invokes Syft with the `all-layers` scanning scope (i.e. the Syft argument `--scope all-layers`).
Expand All @@ -49,4 +28,3 @@ For example:
## Known limitations

- Windows container scanning is not supported
- Multiplatform images are not supported
31 changes: 6 additions & 25 deletions src/Microsoft.ComponentDetection.Common/DockerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,14 @@ public async Task<ContainerDetails> InspectImageAsync(string image, Cancellation
}

public async Task<(string Stdout, string Stderr)> CreateAndRunContainerAsync(string image, IList<string> command, CancellationToken cancellationToken = default)
{
return await this.CreateAndRunContainerAsync(image, command, additionalBinds: null, cancellationToken);
}

public async Task<(string Stdout, string Stderr)> CreateAndRunContainerAsync(string image, IList<string> command, IList<string> additionalBinds, CancellationToken cancellationToken = default)
{
using var record = new DockerServiceTelemetryRecord
{
Image = image,
Command = JsonSerializer.Serialize(command),
};
await this.TryPullImageAsync(image, cancellationToken);
var container = await CreateContainerAsync(image, command, additionalBinds, cancellationToken);
var container = await CreateContainerAsync(image, command, cancellationToken);
record.Container = JsonSerializer.Serialize(container);
var stream = await AttachContainerAsync(container.ID, cancellationToken);
await StartContainerAsync(container.ID, cancellationToken);
Expand All @@ -209,20 +204,8 @@ public async Task<ContainerDetails> InspectImageAsync(string image, Cancellation
private static async Task<CreateContainerResponse> CreateContainerAsync(
string image,
IList<string> command,
IList<string> additionalBinds,
CancellationToken cancellationToken = default)
{
var binds = new List<string>
{
$"{Path.GetTempPath()}:/tmp",
"/var/run/docker.sock:/var/run/docker.sock",
};

if (additionalBinds != null)
{
binds.AddRange(additionalBinds);
}

var parameters = new CreateContainerParameters
{
Image = image,
Expand All @@ -238,7 +221,11 @@ private static async Task<CreateContainerResponse> CreateContainerAsync(
[
"no-new-privileges",
],
Binds = binds,
Binds =
[
$"{Path.GetTempPath()}:/tmp",
"/var/run/docker.sock:/var/run/docker.sock",
],
},
};
return await Client.Containers.CreateContainerAsync(parameters, cancellationToken);
Expand Down Expand Up @@ -275,10 +262,4 @@ private static int GetContainerId()
{
return Interlocked.Increment(ref incrementingContainerId);
}

/// <inheritdoc/>
public ContainerDetails GetEmptyContainerDetails()
{
return new ContainerDetails { Id = GetContainerId() };
}
}
19 changes: 1 addition & 18 deletions src/Microsoft.ComponentDetection.Contracts/IDockerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,9 @@ public interface IDockerService
/// <summary>
/// Creates and runs a container with the given image and command.
/// </summary>
/// <param name="image">The image to run.</param>
/// <param name="image">The image to inspect.</param>
/// <param name="command">The command to run in the container.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A tuple of stdout and stderr from the container.</returns>
Task<(string Stdout, string Stderr)> CreateAndRunContainerAsync(string image, IList<string> command, CancellationToken cancellationToken = default);

/// <summary>
/// Creates and runs a container with the given image, command, and additional volume binds.
/// </summary>
/// <param name="image">The image to run.</param>
/// <param name="command">The command to run in the container.</param>
/// <param name="additionalBinds">Additional volume bind mounts to add to the container (e.g., "/host/path:/container/path:ro").</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A tuple of stdout and stderr from the container.</returns>
Task<(string Stdout, string Stderr)> CreateAndRunContainerAsync(string image, IList<string> command, IList<string> additionalBinds, CancellationToken cancellationToken = default);

/// <summary>
/// Creates an empty <see cref="ContainerDetails"/> with a unique ID assigned.
/// Used for image types where details are not obtained from Docker inspect (e.g., OCI layout images).
/// </summary>
/// <returns>A <see cref="ContainerDetails"/> with only the <see cref="ContainerDetails.Id"/> populated.</returns>
ContainerDetails GetEmptyContainerDetails();
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ namespace Microsoft.ComponentDetection.Detectors.Linux;
using System.Threading.Tasks;
using Microsoft.ComponentDetection.Contracts.BcdeModels;
using Microsoft.ComponentDetection.Contracts.TypedComponent;
using Microsoft.ComponentDetection.Detectors.Linux.Contracts;

/// <summary>
/// Interface for scanning Linux container layers to identify components.
Expand All @@ -14,7 +13,6 @@ public interface ILinuxScanner
{
/// <summary>
/// Scans a Linux container image for components and maps them to their respective layers.
/// Runs Syft and processes the output in a single step.
/// </summary>
/// <param name="imageHash">The hash identifier of the container image to scan.</param>
/// <param name="containerLayers">The collection of Docker layers that make up the container image.</param>
Expand All @@ -31,33 +29,4 @@ public Task<IEnumerable<LayerMappedLinuxComponents>> ScanLinuxAsync(
LinuxScannerScope scope,
CancellationToken cancellationToken = default
);

/// <summary>
/// Runs the Syft scanner and returns the raw parsed output without processing components.
/// Use this when the caller needs access to the full Syft output (e.g., to extract source metadata for OCI images).
/// </summary>
/// <param name="syftSource">The source argument passed to Syft (e.g., an image hash or "oci-dir:/oci-image").</param>
/// <param name="additionalBinds">Additional volume bind mounts for the Syft container (e.g., for mounting OCI directories).</param>
/// <param name="scope">The scope for scanning the image.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the parsed <see cref="SyftOutput"/>.</returns>
public Task<SyftOutput> GetSyftOutputAsync(
string syftSource,
IList<string> additionalBinds,
LinuxScannerScope scope,
CancellationToken cancellationToken = default
);

/// <summary>
/// Processes parsed Syft output into layer-mapped components.
/// </summary>
/// <param name="syftOutput">The parsed Syft output.</param>
/// <param name="containerLayers">The layers to map components to.</param>
/// <param name="enabledComponentTypes">The set of component types to include in the results.</param>
/// <returns>A collection of <see cref="LayerMappedLinuxComponents"/> representing the components found and their associated layers.</returns>
public IEnumerable<LayerMappedLinuxComponents> ProcessSyftOutput(
SyftOutput syftOutput,
IEnumerable<DockerLayer> containerLayers,
ISet<ComponentType> enabledComponentTypes
);
}

This file was deleted.

Loading
Loading