Skip to content

feat: add docker build detection #409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 8, 2023
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
9 changes: 9 additions & 0 deletions scripts/dev_scripts/integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ python $COMPARE_DEPS $DEP_RESULT $DEP_EXPECTED || log_fail

python $COMPARE_JSON_OUT $JSON_RESULT $JSON_EXPECTED || log_fail

echo "timyarkov/docker_test: Analyzing the repo path, the branch name and the commit digest"
echo "when automatic dependency resolution is skipped, for a project using docker as a build tool."
echo -e "----------------------------------------------------------------------------------\n"
JSON_EXPECTED=$WORKSPACE/tests/e2e/expected_results/docker_test/docker_test.json
JSON_RESULT=$WORKSPACE/output/reports/github.com/timyarkov/docker_test/docker_test.json
$RUN_MACARON analyze -rp https://github.com/timyarkov/docker_test -b main -d 404a51a2f38c4470af6b32e4e00b5318c2d7c0cc --skip-deps || log_fail

python $COMPARE_JSON_OUT $JSON_RESULT $JSON_EXPECTED || log_fail

echo -e "\n----------------------------------------------------------------------------------"
echo "apache/maven: Analyzing with PURL and repository path without dependency resolution."
echo -e "----------------------------------------------------------------------------------\n"
Expand Down
18 changes: 18 additions & 0 deletions src/macaron/config/defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,24 @@ deploy_arg =
[builder.poetry.ci.deploy]
github_actions = pypa/gh-action-pypi-publish

# This is the spec for trusted Docker build tool usages.
[builder.docker]
entry_conf =
# Also account for if there's multiple dockerfiles, e.g. test.Dockerfile
build_configs =
Dockerfile
Dockerfile.*
*.Dockerfile
builder =
docker
build_arg =
build
deploy_arg =
push
[builder.docker.ci.deploy]
github_actions =
docker/build-push-action

# This is the spec for GitHub Actions CI.
[ci.github_actions]
entry_conf =
Expand Down
3 changes: 2 additions & 1 deletion src/macaron/slsa_analyzer/build_tool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"""The build_tool package contains the supported build tools for Macaron."""

from .base_build_tool import BaseBuildTool
from .docker import Docker
from .gradle import Gradle
from .maven import Maven
from .pip import Pip
from .poetry import Poetry

# The list of supported build tools. The order of the list determine the order
# in which each build tool is checked against the target repository.
BUILD_TOOLS: list[BaseBuildTool] = [Gradle(), Maven(), Poetry(), Pip()]
BUILD_TOOLS: list[BaseBuildTool] = [Gradle(), Maven(), Poetry(), Pip(), Docker()]
92 changes: 92 additions & 0 deletions src/macaron/slsa_analyzer/build_tool/docker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright (c) 2023 - 2023, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.

"""This module contains the Docker class which inherits BaseBuildTool.

This module is used to work with repositories that use Docker as a build tool.
"""

from macaron.config.defaults import defaults
from macaron.dependency_analyzer.dependency_resolver import NoneDependencyAnalyzer
from macaron.slsa_analyzer.build_tool.base_build_tool import BaseBuildTool, file_exists


class Docker(BaseBuildTool):
"""This class contains the information of Docker when used as a build tool."""

def __init__(self) -> None:
"""Initialize instance."""
super().__init__(name="docker")

def load_defaults(self) -> None:
"""Load the default values from defaults.ini."""
if "builder.docker" in defaults:
for item in defaults["builder.docker"]:
if hasattr(self, item):
setattr(self, item, defaults.get_list("builder.docker", item))

if "builder.docker.ci.deploy" in defaults:
for item in defaults["builder.docker.ci.deploy"]:
if item in self.ci_deploy_kws:
self.ci_deploy_kws[item] = defaults.get_list("builder.docker.ci.deploy", item)

def is_detected(self, repo_path: str) -> bool:
"""Return True if this build tool is used in the target repo.

Parameters
----------
repo_path : str
The path to the target repo.

Returns
-------
bool
True if this build tool is detected, else False.
"""
for file in self.build_configs:
if file_exists(repo_path, file):
return True

return False

def prepare_config_files(self, wrapper_path: str, build_dir: str) -> bool:
"""Make necessary preparations for using this build tool.

Parameters
----------
wrapper_path : str
The path where all necessary wrapper files are located.
build_dir : str
The path of the build dir. This is where all files are copied to.

Returns
-------
bool
True if succeed else False.
"""
# TODO: Future dependency analysis may require some preprocessing, e.g.
# saving images to tar files. Need to investigate when implementing
# and work with this method accordingly.

return False

def get_dep_analyzer(self, repo_path: str) -> NoneDependencyAnalyzer:
"""Create a DependencyAnalyzer for the Docker build tool. Currently unimplemented.

Parameters
----------
repo_path: str
The path to the target repo.

Returns
-------
NoneDependencyAnalyser
The NoneDependencyAnalyser object.

Raises
------
DependencyAnalyzerError
"""
# TODO: Find a suitable tool to analyse dependencies; as of now Syft
# seems to be a good option, but need to experiment.
return NoneDependencyAnalyzer()
20 changes: 20 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from macaron.config.defaults import create_defaults, defaults, load_defaults
from macaron.database.table_definitions import Analysis, Component, Repository
from macaron.slsa_analyzer.analyze_context import AnalyzeContext
from macaron.slsa_analyzer.build_tool.docker import Docker
from macaron.slsa_analyzer.build_tool.gradle import Gradle
from macaron.slsa_analyzer.build_tool.maven import Maven
from macaron.slsa_analyzer.build_tool.pip import Pip
Expand Down Expand Up @@ -148,6 +149,25 @@ def pip_tool(setup_test) -> Pip: # type: ignore # pylint: disable=unused-argume
return pip


@pytest.fixture(autouse=True)
def docker_tool(setup_test) -> Docker: # type: ignore # pylint: disable=unused-argument
"""Create a Docker tool instance.

Parameters
----------
setup_test
Depends on setup_test fixture.

Returns
-------
Docker
The Docker instance.
"""
docker = Docker()
docker.load_defaults()
return docker


class MockGitHubActions(GitHubActions):
"""Mock the GitHubActions class."""

Expand Down
Loading