diff --git a/.gitignore b/.gitignore index e2e553ee596..52063a7b016 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ /*.pem /keys /roles +/Licenses.toml +/licenses diff --git a/BUILDING.md b/BUILDING.md index 7972068aa32..add28ce7939 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -92,6 +92,35 @@ cargo make -e BUILDSYS_ARCH=my-arch-here (You can use variant and arch arguments together, too.) +#### Package licenses + +Most packages will include license files extracted from upstream source archives. +However, in some rare cases there are multiple licenses that could apply to a package. +Bottlerocket's build system uses the `Licenses.toml` file in conjuction with the `licenses` directory to configure the licenses used for such special packages. +Here is an example of a simple `Licenses.toml` configuration file: + +```toml +[package] +spdx-id = "SPDX-ID" +licenses = [ + { path = "the-license.txt" } +] +``` + +In the previous example, it is expected that the file `the-license.txt` is present in `licenses`. +You can retrieve the licenses from a remote endpoint, or the local filesystem if you specify the `license-url` field: + +```toml +[package] +spdx-id = "SPDX-ID AND SPDX-ID-2" # Package with multiple licenses +licenses = [ + # This file is copied from a file system, and will be saved as `path` + { license-url = "file:///path/to/spdx-id-license.txt", path = "spdx-id-license.txt" }, + # This file is fetched from an https endpoint, and will be saved as `path` + { license-url = "https://localhost/spdx-id-license-v2.txt", path = "spdx-id-license-2.txt" } +] +``` + ### Register an AMI To use the image in Amazon EC2, we need to register the image as an AMI. diff --git a/Dockerfile b/Dockerfile index e769379b5cb..569288dd5ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -68,6 +68,16 @@ WORKDIR /home/builder USER builder ENV PACKAGE=${PACKAGE} ARCH=${ARCH} COPY --chown=builder roles/${REPO}.root.json ./rpmbuild/BUILD/root.json +# We attempt to copy `Licenses.toml` and `licenses` for the current build, otherwise +# an empty file and a directory are created so that `bottlerocket-license-tool` will +# fail with a more descriptive error message. +RUN --mount=target=/host \ + ( [ -f /host/Licenses.toml ] \ + && cp /host/Licenses.toml ./rpmbuild/BUILD/ \ + || touch ./rpmbuild/BUILD/Licenses.toml ) \ + && ( [ -d /host/licenses ] \ + && cp -r /host/licenses ./rpmbuild/BUILD/ \ + || mkdir ./rpmbuild/BUILD/licenses ) COPY ./macros/${ARCH} ./macros/shared ./macros/rust ./macros/cargo ./packages/${PACKAGE}/ . RUN rpmdev-setuptree \ && cat ${ARCH} shared rust cargo > .rpmmacros \ diff --git a/Makefile.toml b/Makefile.toml index 7b1758ebdad..c4b0f2a2eca 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -57,6 +57,10 @@ PUBLISH_UNIFIED_VOLUME_SIZE = "22" # tools/pubsys/policies/ssm/README.md for more information. PUBLISH_SSM_TEMPLATES_PATH = "${BUILDSYS_ROOT_DIR}/tools/pubsys/policies/ssm/defaults.toml" +# This can be overriden with -e to change the source path +# for the Licenses.toml file +BUILDSYS_LICENSES_CONFIG_PATH = "${BUILDSYS_ROOT_DIR}/Licenses.toml" + # Specifies whether to validate all targets when validating TUF repositories REPO_VALIDATE_TARGETS = "true" # Specifies the timeframe to look for upcoming repository metadata expirations @@ -89,6 +93,10 @@ BUILDSYS_UPSTREAM_SOURCE_FALLBACK = "false" # if the license check fails. BUILDSYS_ALLOW_FAILED_LICENSE_CHECK = "false" +# Disallow pulling licenses from Upstream URLs. To fetch licenses from the upstream source, +# override this on the command line and set it to 'true' +BUILDSYS_UPSTREAM_LICENSE_FETCH= "false" + # This controls how many `docker build` commands we'll invoke at once. BUILDSYS_JOBS = "8" @@ -391,7 +399,7 @@ fi # Builds a package including its build-time and runtime dependency packages. [tasks.build-package] -dependencies = ["check-cargo-version", "build-tools", "publish-setup"] +dependencies = ["check-cargo-version", "build-tools", "publish-setup", "fetch-licenses"] script_runner = "bash" script = [ ''' @@ -605,6 +613,44 @@ docker run --rm \ ''' ] +[tasks.fetch-licenses] +dependencies = ["fetch"] +script = [ +''' +if [ "${BUILDSYS_UPSTREAM_LICENSE_FETCH}" = "false" ]; then + echo "Skipping fetching licenses" + exit 0 +fi + +# Attempt copy Licenses.toml +cp "${BUILDSYS_LICENSES_CONFIG_PATH}" "${BUILDSYS_ROOT_DIR}/Licenses.toml" 2>/dev/null \ + || echo "Skipping copying file from ${BUILDSYS_LICENSES_CONFIG_PATH}" + +if [ ! -s "${BUILDSYS_ROOT_DIR}"/Licenses.toml ] ; then + echo "Not fetching licenses since 'Licenses.toml' doesn't exist" + exit 0 +fi + +mkdir -p "${BUILDSYS_ROOT_DIR}"/licenses + +run_fetch_licenses=" +bottlerocket-license-tool -l /tmp/Licenses.toml fetch /tmp/licenses +" +set +e + +docker run --rm \ + --user "$(id -u):$(id -g)" \ + --security-opt label:disable \ + -e CARGO_HOME="/tmp/.cargo" \ + -v "${CARGO_HOME}":/tmp/.cargo \ + -v "${BUILDSYS_ROOT_DIR}/licenses:/tmp/licenses" \ + -v "${BUILDSYS_ROOT_DIR}/Licenses.toml:/tmp/Licenses.toml" \ + "${BUILDSYS_SDK_IMAGE}" \ + bash -c "${run_fetch_licenses}" +''' +] + + [tasks.link-clean] dependencies = ["fetch"] script = [ @@ -642,6 +688,7 @@ fi dependencies = [ "link-clean", "check-licenses", + "fetch-licenses", "build-variant", "build-ova", "link-variant",