Skip to content

Commit

Permalink
Add cyclonedx-lib build and --create-sbom option (#2805)
Browse files Browse the repository at this point in the history
* Add cyclonedx-lib build and --create-sbom option

Signed-off-by: Andrew Leonard <[email protected]>
  • Loading branch information
andrew-m-leonard authored Dec 17, 2021
1 parent d5e5516 commit 6a577e0
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
*.iml
.vscode/
workspace
cyclonedx-lib/build
**/.DS_Store
build-farm/platform-specific-configurations/platformConfigFile.sh
133 changes: 133 additions & 0 deletions cyclonedx-lib/build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?xml version="1.0"?>

<!--
# Licensed 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
#
# https://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.
-->

<project name="cyclonedx-lib build" default="build" basedir=".">
<taskdef resource="net/sf/antcontrib/antlib.xml" />

<!-- Dependency versions -->
<property name="cyclonedx-core-java-version" value="5.0.4"/>
<property name="jackson-version" value="2.12.4"/>
<property name="json-schema-version" value="1.0.58"/>
<property name="commons-codec-version" value="1.15"/>
<property name="commons-io-version" value="2.11.0"/>
<property name="github-package-url-version" value="1.4.0"/>

<!-- classpath for running application -->
<property name="classpath" value="build/jar/temurin-gen-sbom.jar:build/jar/cyclonedx-core-java.jar:build/jar/jackson-core.jar:build/jar/jackson-dataformat-xml.jar:build/jar/jackson-databind.jar:build/jar/jackson-annotations.jar:build/jar/json-schema.jar:build/jar/commons-codec.jar:build/jar/commons-io.jar:build/jar/github-package-url.jar"/>

<target name="dep-checks">
<available file="build/jar/cyclonedx-core-java.jar" property="cyclonedx_available"/>
<available file="build/jar/jackson-core.jar" property="jackson-core_available"/>
<available file="build/jar/jackson-dataformat-xml.jar" property="jackson-core_available"/>
<available file="build/jar/jackson-databind.jar" property="jackson-databind_available"/>
<available file="build/jar/jackson-annotations.jar" property="jackson-annotations_available"/>
<available file="build/jar/json-schema.jar" property="json-schema_available"/>
<available file="build/jar/commons-codec.jar" property="commons-codec_available"/>
<available file="build/jar/commons-io.jar" property="commons-io_available"/>
<available file="build/jar/github-package-url.jar" property="github-package-url_available"/>
</target>

<target name="download-cyclonedx" unless="cyclonedx_available">
<echo message="Downloading cyclonedx-core-java version ${cyclonedx-core-java-version}"/>
<download-file destdir="build/jar" destfile="cyclonedx-core-java.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=org/cyclonedx/cyclonedx-core-java/${cyclonedx-core-java-version}/cyclonedx-core-java-${cyclonedx-core-java-version}.jar"/>
</target>

<target name="download-jackson-core" unless="jackson-core_available">
<echo message="Downloading jackson-core version ${jackson-version}"/>
<download-file destdir="build/jar" destfile="jackson-core.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/fasterxml/jackson/core/jackson-core/${jackson-version}/jackson-core-${jackson-version}.jar"/>
</target>

<target name="download-jackson-dataformat-xml" unless="jackson-core_available">
<echo message="Downloading jackson-dataformat-xml version ${jackson-version}"/>
<download-file destdir="build/jar" destfile="jackson-dataformat-xml.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/fasterxml/jackson/dataformat/jackson-dataformat-xml/${jackson-version}/jackson-dataformat-xml-${jackson-version}.jar"/>
</target>

<target name="download-jackson-databind" unless="jackson-databind_available">
<echo message="Downloading jackson-databind version ${jackson-version}"/>
<download-file destdir="build/jar" destfile="jackson-databind.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/fasterxml/jackson/core/jackson-databind/${jackson-version}/jackson-databind-${jackson-version}.jar"/>
</target>

<target name="download-jackson-annotations" unless="jackson-annotations_available">
<echo message="Downloading jackson-annotations version ${jackson-version}"/>
<download-file destdir="build/jar" destfile="jackson-annotations.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/fasterxml/jackson/core/jackson-annotations/${jackson-version}/jackson-annotations-${jackson-version}.jar"/>
</target>

<target name="download-json-schema" unless="json-schema_available">
<echo message="Downloading json-schema version ${json-schema-version}"/>
<download-file destdir="build/jar" destfile="json-schema.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/networknt/json-schema-validator/${json-schema-version}/json-schema-validator-${json-schema-version}.jar"/>
</target>

<target name="download-commons-codec" unless="commons-codec_available">
<echo message="Downloading commons-codec version ${commons-codec-version}"/>
<download-file destdir="build/jar" destfile="commons-codec.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=commons-codec/commons-codec/${commons-codec-version}/commons-codec-${commons-codec-version}.jar"/>
</target>

<target name="download-commons-io" unless="commons-io_available">
<echo message="Downloading commons-io version ${commons-io-version}"/>
<download-file destdir="build/jar" destfile="commons-io.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=commons-io/commons-io/${commons-io-version}/commons-io-${commons-io-version}.jar"/>
</target>

<target name="download-github-package-url" unless="github-package-url_available">
<echo message="Downloading github-package-url version ${github-package-url-version}"/>
<download-file destdir="build/jar" destfile="github-package-url.jar" srcurl="https://search.maven.org/classic/remotecontent?filepath=com/github/package-url/packageurl-java/${github-package-url-version}/packageurl-java-${github-package-url-version}.jar"/>
</target>

<target name="build" depends="dep-checks, download-cyclonedx, download-jackson-core, download-jackson-dataformat-xml, download-jackson-databind, download-jackson-annotations, download-json-schema, download-commons-codec, download-commons-io, download-github-package-url, compile, jar">
<echo message="Building cyclonedx-lib"/>
</target>

<target name="clean">
<delete dir="build"/>
</target>

<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" classpath="build/jar/cyclonedx-core-java.jar"/>
</target>

<target name="jar">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/temurin-gen-sbom.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="temurin.sbom.TemurinGenSBOM"/>
</manifest>
</jar>
</target>

<target name="run">
<java classpath="${classpath}" classname="temurin.sbom.TemurinGenSBOM"/>
</target>

<macrodef name="download-file" description="Use curl to download a file">
<attribute name="srcurl" description="URL of file to download"/>
<attribute name="destdir" description="Directory in which to place the downloaded file"/>
<attribute name="destfile" description="File name of the downloaded file"/>
<sequential>
<echo message="Executing macro download-file"/>
<echo message="File to download: @{srcurl}"/>
<echo message="Destination: @{destdir}/@{destfile}"/>
<echo message="Download tool: curl"/>
<mkdir dir="@{destdir}"/>
<exec executable="curl">
<arg value="-L"/>
<arg value="-o"/>
<arg value="@{destdir}/@{destfile}"/>
<arg value="@{srcurl}"/>
</exec>
</sequential>
</macrodef>
</project>

69 changes: 69 additions & 0 deletions cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
################################################################################
# Licensed 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
#
# https://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 temurin.sbom;

import org.cyclonedx.BomGeneratorFactory;
import org.cyclonedx.CycloneDxSchema.Version;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Component;
import org.cyclonedx.generators.json.BomJsonGenerator;

/**
* Command line tool to construct a CycloneDX SBOM.
*/
public final class TemurinGenSBOM {
private TemurinGenSBOM() {
}

/**
* Main entry.
* @param args Arguments for sbom operation.
*/
public static void main(final String[] args) {
System.out.print("TemurinGenSBOM:");
for (String arg : args) {
System.out.print(" " + arg);
}
System.out.println("");

Bom bom = createTestBom();
String json = generateBomJson(bom);

System.out.println("SBOM: " + json);
}

static Bom createTestBom() {
Bom bom = new Bom();

Component comp1 = new Component();
comp1.setName("TestComponent");
comp1.setVersion("1.0.0");
comp1.setType(Component.Type.APPLICATION);
comp1.setAuthor("Adoptium");

bom.addComponent(comp1);

return bom;
}

static String generateBomJson(final Bom bom) {
BomJsonGenerator bomGen = BomGeneratorFactory.createJson(Version.VERSION_13, bom);

String json = bomGen.toJsonString();

return json;
}
}
20 changes: 20 additions & 0 deletions cyclonedx-lib/src/temurin/sbom/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
################################################################################
# Licensed 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
#
# https://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.
################################################################################
*/
/**
* Temurin SBOM package.
*/
package temurin.sbom;

61 changes: 61 additions & 0 deletions sbin/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,62 @@ createOpenJDKFailureLogsArchive() {
createArchive "${adoptLogArchiveDir}" "${makeFailureLogsName}"
}

# Build the CycloneDX Java library and app used for SBoM generation
buildCyclonedxLib() {
local javaHome=""

if [ ${JAVA_HOME+x} ] && [ -d "${JAVA_HOME}" ]; then
javaHome=${JAVA_HOME}
elif [ ${JDK8_BOOT_DIR+x} ] && [ -d "${JDK8_BOOT_DIR}" ]; then
javaHome=${JDK8_BOOT_DIR}
elif [ ${JDK11_BOOT_DIR+x} ] && [ -d "${JDK11_BOOT_DIR}" ]; then
javaHome=${JDK11_BOOT_DIR}
else
echo "Unable to find a suitable JAVA_HOME to build the cyclonedx-lib"
exit 2
fi

# We need the exitcode from ant
set +eu

ant -f "${WORKSPACE}/cyclonedx-lib/build.xml" -Djava.home="${javaHome}" clean
ant -f "${WORKSPACE}/cyclonedx-lib/build.xml" -Djava.home="${javaHome}" build
exitCode=$?

set -eu

if [ "${exitCode}" -ne 0 ]; then
echo "Failed to build the cyclonedx-lib, exiting"
exit ${exitCode}
fi
}

# Generate the SBoM
generateSBoM() {
local javaHome=""

if [ ${JAVA_HOME+x} ] && [ -d "${JAVA_HOME}" ]; then
javaHome=${JAVA_HOME}
elif [ ${JDK8_BOOT_DIR+x} ] && [ -d "${JDK8_BOOT_DIR}" ]; then
javaHome=${JDK8_BOOT_DIR}
elif [ ${JDK11_BOOT_DIR+x} ] && [ -d "${JDK11_BOOT_DIR}" ]; then
javaHome=${JDK11_BOOT_DIR}
else
echo "Unable to find a suitable JAVA_HOME to run the TemurinGenSBOM app"
exit 2
fi

# classpath to run CycloneDX java app TemurinGenSBOM
classpath="${WORKSPACE}/cyclonedx-lib/build/jar/temurin-gen-sbom.jar:${WORKSPACE}/cyclonedx-lib/build/jar/cyclonedx-core-java.jar:${WORKSPACE}/cyclonedx-lib/build/jar/jackson-core.jar:${WORKSPACE}/cyclonedx-lib/build/jar/jackson-dataformat-xml.jar:${WORKSPACE}/cyclonedx-lib/build/jar/jackson-databind.jar:${WORKSPACE}/cyclonedx-lib/build/jar/jackson-annotations.jar:${WORKSPACE}/cyclonedx-lib/build/jar/json-schema.jar:${WORKSPACE}/cyclonedx-lib/build/jar/commons-codec.jar:${WORKSPACE}/cyclonedx-lib/build/jar/commons-io.jar:${WORKSPACE}/cyclonedx-lib/build/jar/github-package-url.jar"

# Run app to generate SBoM

# Examples..
"${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --create temurin_sbom.json --name "Temurin SBOM" --version "1.2.3" --type "application" --author "Adoptium"
"${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --add_component temurin_sbom.json --name "openjdk" --version "1.0.0" --hash "abcdefg123456"
"${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --add_dependency temurin_sbom.json --name "gcc" --version "8.5.0"
}

getGradleJavaHome() {
local gradleJavaHome=""

Expand Down Expand Up @@ -1593,6 +1649,11 @@ if [[ "${BUILD_CONFIG[MAKE_EXPLODED]}" != "true" ]]; then
createOpenJDKTarArchive
fi

if [[ "${BUILD_CONFIG[CREATE_SBOM]}" == "true" ]]; then
buildCyclonedxLib
generateSBoM
fi

echo "build.sh : $(date +%T) : All done!"

# ccache is not detected properly TODO
Expand Down
7 changes: 7 additions & 0 deletions sbin/common/config_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ COPY_MACOSX_FREE_FONT_LIB_FOR_JRE_FLAG
COPY_TO_HOST
CREATE_DEBUG_IMAGE
CREATE_JRE_IMAGE
CREATE_SBOM
CREATE_SOURCE_ARCHIVE
CUSTOM_CACERTS
CROSSCOMPILE
Expand Down Expand Up @@ -240,6 +241,9 @@ function parseConfigurationArguments() {
"--create-jre-image" )
BUILD_CONFIG[CREATE_JRE_IMAGE]=true;;

"--create-sbom" )
BUILD_CONFIG[CREATE_SBOM]=true;;

"--create-source-archive" )
BUILD_CONFIG[CREATE_SOURCE_ARCHIVE]=true;;

Expand Down Expand Up @@ -459,6 +463,9 @@ function configDefaults() {
# The default behavior of whether we want to create the legacy JRE
BUILD_CONFIG[CREATE_JRE_IMAGE]="false"

# Do not create an SBOM by default
BUILD_CONFIG[CREATE_SBOM]="false"

# The default behavior of whether we want to create a separate source archive
BUILD_CONFIG[CREATE_SOURCE_ARCHIVE]="false"

Expand Down

0 comments on commit 6a577e0

Please sign in to comment.