Skip to content

Commit a7ba60e

Browse files
committed
Co-authored-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
Signed-off-by: Varsha U N <varshamaddur2006@gmail.com> Signed-off-by: Varsha U N <varshamaddur2006@gmail.com> Co-authored-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com> Signed-off-by: Varsha U N <varshamaddur2006@gmail.com> Update dockerfile.py Signed-off-by: Varsha U N <varshamaddur2006@gmail.com>
1 parent 785ea09 commit a7ba60e

10 files changed

+243
-34
lines changed

src/packagedcode/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from packagedcode import debian
2121
from packagedcode import debian_copyright
2222
from packagedcode import distro
23-
from packagedcode import dockerfileLABEL
23+
from packagedcode import dockerfile
2424
from packagedcode import conda
2525
from packagedcode import conan
2626
from packagedcode import cocoapods
@@ -98,7 +98,7 @@
9898
debian.DebianSourcePackageTarballHandler,
9999

100100
distro.EtcOsReleaseHandler,
101-
dockerfileLABEL.DockerfileHandler,
101+
dockerfile.DockerfileHandler,
102102

103103
freebsd.CompactManifestHandler,
104104

src/packagedcode/dockerfileLABEL.py renamed to src/packagedcode/dockerfile.py

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,33 @@
1414
from dockerfile_parse import DockerfileParser
1515
from packagedcode import models
1616
from packagedcode import utils
17+
import fnmatch
1718

1819

1920
class DockerfileHandler(models.DatafileHandler):
20-
datasource_id = 'dockerfile'
21-
default_package_type = 'docker-image'
22-
path_patterns = ('Dockerfile', 'containerfile', '*.dockerfile')
23-
description = 'Dockerfile (OCI) metadata handler'
24-
documentation_url = 'https://docs.docker.com/engine/reference/builder/'
25-
21+
datasource_id = 'dockerfile_oci_labels'
22+
23+
@classmethod
24+
def is_datafile(cls, path):
25+
patterns = ['Dockerfile', 'containerfile', '*.dockerfile']
26+
filename=os.path.basename(path)
27+
for pattern in patterns:
28+
if fnmatch.fnmatch(filename, pattern):
29+
return True
30+
return False
31+
2632
@classmethod
2733
def parse(cls, location, package_only=False):
2834
"""
2935
Parse a Dockerfile and yield one or more PackageData objects with OCI labels and metadata.
3036
"""
3137
labels = cls.extract_oci_labels_from_dockerfile(location)
32-
33-
3438
package_data = {
3539
'datasource_id': cls.datasource_id,
3640
'type': cls.default_package_type,
37-
'name': labels.get('name', 'unknown'),
38-
'version': labels.get('version', 'unknown'),
39-
'license_expression': labels.get('license', 'unknown'),
41+
'name': labels.get('name', 'None'),
42+
'version': labels.get('version', 'None'),
43+
'license_expression': labels.get('license', 'None'),
4044
'labels': labels,
4145
}
4246

@@ -45,28 +49,11 @@ def parse(cls, location, package_only=False):
4549
@classmethod
4650
def extract_oci_labels_from_dockerfile(cls, dockerfile_path):
4751
"""
48-
Extract OCI labels from the Dockerfile using container-inspector.
52+
Extract OCI labels from the Dockerfile using DockerfileParser.
4953
"""
5054
labels = {}
5155
parser = DockerfileParser()
52-
parser.parse(dockerfile_path)
53-
labels = parser.labels
56+
with open(dockerfile_path, 'r') as dockerfile:
57+
parser.content = dockerfile.read()
58+
labels = parser.labels
5459
return labels
55-
56-
@classmethod
57-
def assemble(cls, package_data, resource, codebase, package_adder):
58-
"""
59-
Assemble a Package from the parsed Dockerfile data.
60-
"""
61-
if package_data.purl:
62-
package = models.Package.from_package_data(package_data=package_data, datafile_path=resource.path)
63-
64-
65-
package.populate_license_fields()
66-
67-
yield package
68-
69-
70-
package_adder(package.package_uid, resource, codebase)
71-
72-
yield resource
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"datasource_id": "dockerfile_oci_labels",
4+
"type": "default",
5+
"name": "Unknown",
6+
"version": "Unknown",
7+
"license_expression": "GPL-2.0-only AND BSD-2-Clause",
8+
"labels": {
9+
"source": "https://github.com/kubernetes-sigs/blixt",
10+
"licenses": "GPL-2.0-only,BSD-2-Clause"
11+
}
12+
}
13+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"datasource_id": "dockerfile_oci_labels",
4+
"type": "default",
5+
"license_expression": "MIT",
6+
"labels": {
7+
"source": "https://github.com/kreneskyp/ix"
8+
}
9+
}
10+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM postgres:15.3
2+
LABEL org.opencontainers.image.source https://github.com/kreneskyp/ix
3+
4+
RUN apt update -y && \
5+
apt install -y postgresql-15-pgvector \
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[
2+
{
3+
"datasource_id": "dockerfile_oci_labels",
4+
"type": "default",
5+
"name": "Kanboard",
6+
"version": "1.2.42",
7+
"license_expression": "MIT",
8+
"labels": {
9+
"source": "https://github.com/kanboard/kanboard",
10+
"title": "Kanboard",
11+
"description": "Kanboard is project management software that focuses on the Kanban methodology",
12+
"vendor": "Kanboard",
13+
"licenses": "MIT",
14+
"url": "https://kanboard.org",
15+
"documentation": "https://docs.kanboard.org"
16+
}
17+
}
18+
]
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#Copied from https://github.com/kubernetes-sigs/blixt/blob
2+
3+
4+
FROM rust:1.79-slim-bookworm as builder
5+
6+
ARG TARGETARCH
7+
ARG LLVM_VERSION=19
8+
9+
RUN apt-get update
10+
RUN apt-get install --yes \
11+
build-essential \
12+
protobuf-compiler \
13+
pkg-config \
14+
musl-tools \
15+
clang \
16+
wget
17+
18+
RUN apt install --yes lsb-release software-properties-common gnupg
19+
RUN wget -O /tmp/llvm.sh https://apt.llvm.org/llvm.sh
20+
RUN chmod +x /tmp/llvm.sh
21+
RUN /bin/sh -c "/tmp/llvm.sh ${LLVM_VERSION} all"
22+
23+
RUN rustup default stable
24+
RUN rustup install nightly
25+
RUN rustup component add rust-src --toolchain nightly
26+
RUN --mount=type=cache,target=/root/.cargo/registry \
27+
cargo install bpf-linker
28+
29+
WORKDIR /workspace
30+
# Docker uses the amd64/arm64 convention while Rust uses the x86_64/aarch64 convention.
31+
# Since Dockerfile doesn't support conditional variables (sigh), write the arch in Rust's
32+
# convention to a file for later usage.
33+
RUN if [ "$TARGETARCH" = "amd64" ]; \
34+
then echo "x86_64" >> arch; \
35+
else echo "aarch64" >> arch; \
36+
fi
37+
RUN rustup target add $(eval cat arch)-unknown-linux-musl
38+
39+
COPY dataplane dataplane
40+
COPY tools/udp-test-server tools/udp-test-server
41+
COPY xtask xtask
42+
COPY Cargo.toml Cargo.toml
43+
COPY Cargo.lock Cargo.lock
44+
COPY .cargo .cargo
45+
46+
# We need to tell bpf-linker where it can find LLVM's shared library file.
47+
# Ref: https://github.com/aya-rs/rustc-llvm-proxy/blob/cbcb3c6/src/lib.rs#L48
48+
ENV LD_LIBRARY_PATH="/usr/lib/llvm-$LLVM_VERSION/lib"
49+
ENV CC_aarch64_unknown_linux_musl="/usr/lib/llvm-$LLVM_VERSION/bin/clang"
50+
ENV AR_aarch64_unknown_linux_musl="/usr/lib/llvm-$LLVM_VERSION/bin/llvm-ar"
51+
ENV CC_x86_64_unknown_linux_musl="/usr/lib/llvm-$LLVM_VERSION/bin/clang"
52+
ENV AR_x86_64_unknown_linux_musl="/usr/lib/llvm-$LLVM_VERSION/bin/llvm-ar"
53+
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-Clink-self-contained=yes -Clinker=rust-lld"
54+
55+
RUN --mount=type=cache,target=/workspace/target/ \
56+
--mount=type=cache,target=/root/.cargo/registry \
57+
cargo xtask build-ebpf --release
58+
RUN --mount=type=cache,target=/workspace/target/ \
59+
--mount=type=cache,target=/root/.cargo/registry \
60+
RUSTFLAGS=-Ctarget-feature=+crt-static cargo build \
61+
--workspace \
62+
--exclude ebpf \
63+
--release \
64+
--target=$(eval cat arch)-unknown-linux-musl
65+
RUN --mount=type=cache,target=/workspace/target/ \
66+
cp /workspace/target/$(eval cat arch)-unknown-linux-musl/release/loader /workspace/dataplane-release
67+
68+
FROM alpine
69+
70+
LABEL org.opencontainers.image.source=https://github.com/kubernetes-sigs/blixt
71+
LABEL org.opencontainers.image.licenses=GPL-2.0-only,BSD-2-Clause
72+
73+
WORKDIR /opt/blixt/
74+
75+
COPY --from=builder /workspace/dataplane-release /opt/blixt/dataplane
76+
77+
COPY dataplane/LICENSE.GPL-2.0 /opt/blixt/LICENSE.GPL-2.0
78+
COPY dataplane/LICENSE.BSD-2-Clause /opt/blixt/LICENSE.BSD-2-Clause
79+
80+
ENTRYPOINT ["/opt/blixt/dataplane"]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#Copied from https://github.com/kanboard/kanboard
2+
3+
FROM alpine:3.21
4+
5+
LABEL org.opencontainers.image.source https://github.com/kanboard/kanboard
6+
LABEL org.opencontainers.image.title=Kanboard
7+
LABEL org.opencontainers.image.description="Kanboard is project management software that focuses on the Kanban methodology"
8+
LABEL org.opencontainers.image.vendor=Kanboard
9+
LABEL org.opencontainers.image.licenses=MIT
10+
LABEL org.opencontainers.image.url=https://kanboard.org
11+
LABEL org.opencontainers.image.documentation=https://docs.kanboard.org
12+
13+
VOLUME /var/www/app/data
14+
VOLUME /var/www/app/plugins
15+
VOLUME /etc/nginx/ssl
16+
17+
EXPOSE 80 443
18+
19+
ARG VERSION
20+
21+
RUN apk --no-cache --update add \
22+
tzdata openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php83 php83-phar php83-curl \
23+
php83-fpm php83-json php83-zlib php83-xml php83-dom php83-ctype php83-opcache php83-zip php83-iconv \
24+
php83-pdo php83-pdo_mysql php83-pdo_sqlite php83-pdo_pgsql php83-mbstring php83-session php83-bcmath \
25+
php83-gd php83-openssl php83-sockets php83-posix php83-ldap php83-simplexml php83-xmlwriter && \
26+
rm -rf /var/www/localhost && \
27+
rm -f /etc/php83/php-fpm.d/www.conf && \
28+
ln -sf /usr/bin/php83 /usr/bin/php
29+
30+
ADD . /var/www/app
31+
ADD docker/ /
32+
33+
RUN rm -rf /var/www/app/docker && echo $VERSION > /var/www/app/app/version.txt
34+
35+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
36+
CMD []

tests/packagedcode/test_dockerfile.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# ScanCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/nexB/scancode-toolkit for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
from packagedcode import dockerfile
11+
import pytest
12+
import os.path
13+
import json
14+
from pathlib import Path
15+
from packagedcode.dockerfile import DockerfileHandler
16+
17+
class TestDockerfileHandler:
18+
19+
def get_test_loc(self, path):
20+
return Path(os.path.join(os.path.dirname(__file__), 'data'))
21+
22+
def load_expected(self, expected_file):
23+
with open(expected_file) as f:
24+
return json.load(f)
25+
26+
def test_is_datafile(self):
27+
dockerfiles = [
28+
'test.dockerfile',
29+
'test.containerfile',
30+
'psql.dockerfile'
31+
]
32+
for dockerfile in dockerfiles:
33+
test_file = self.get_test_loc(f'data/docker/{dockerfile}')
34+
assert DockerfileHandler.is_datafile(str(test_file))
35+
36+
def test_parse_dockerfile(self):
37+
test_files = [
38+
('test.dockerfile', 'test-dockerfile-expected.json'),
39+
('test.containerfile', 'containerfile-expected.json'),
40+
('psql.dockerfile', 'psql-expected.json')
41+
]
42+
for dockerfile, expected in test_files:
43+
test_file = self.get_test_loc(f'data/docker/{dockerfile}')
44+
expected_loc = self.get_test_loc(f'data/docker/{expected}')
45+
packages = list(DockerfileHandler.parse(str(test_file)))
46+
expected_packages = self.load_expected(expected_loc)
47+
assert packages == expected_packages
48+
49+
def test_extract_oci_labels_from_dockerfile(self, mocker):
50+
dockerfiles = [
51+
'test.dockerfile',
52+
'test.containerfile',
53+
'psql.dockerfile'
54+
]
55+
for dockerfile in dockerfiles:
56+
dockerfile_path = self.get_test_loc(f'data/docker/{dockerfile}')
57+
labels = DockerfileHandler.extract_oci_labels_from_dockerfile(str(dockerfile_path))
58+
expected_loc = self.get_test_loc(f'data/docker/{dockerfile.replace(".dockerfile", "-expected.json").replace(".containerfile", "-expected.json")}')
59+
expected_labels = self.load_expected(expected_loc)[0]['labels']
60+
assert labels == expected_labels

0 commit comments

Comments
 (0)