#!/usr/bin/env bash # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. # # 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 # # http://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. function build::common::ensure_tar() { if [[ -n "${TAR:-}" ]]; then return fi # Find gnu tar if it is available, bomb out if not. TAR=tar if which gtar &>/dev/null; then TAR=gtar elif which gnutar &>/dev/null; then TAR=gnutar fi if ! "${TAR}" --version | grep -q GNU; then echo " !!! Cannot find GNU tar. Build on Linux or install GNU tar" echo " on Mac OS X (brew install gnu-tar)." return 1 fi } # Build a release tarball. $1 is the output tar name. $2 is the base directory # of the files to be packaged. This assumes that ${2}/kubernetes is what is # being packaged. function build::common::create_tarball() { build::common::ensure_tar local -r tarfile=$1 local -r stagingdir=$2 local -r repository=$3 "${TAR}" czf "${tarfile}" -C "${stagingdir}" $repository --owner=0 --group=0 } # Generate shasum of tarballs. $1 is the directory of the tarballs. function build::common::generate_shasum() { local -r tarpath=$1 echo "Writing artifact hashes to shasum files..." if [ ! -d "$tarpath" ]; then echo " Unable to find tar directory $tarpath" exit 1 fi cd $tarpath for file in $(find . -name '*.tar.gz'); do filepath=$(basename $file) sha256sum "$filepath" > "$file.sha256" sha512sum "$filepath" > "$file.sha512" done cd - } function build::common::upload_artifacts() { local -r artifactspath=$1 local -r artifactsbucket=$2 local -r projectpath=$3 local -r buildidentifier=$4 local -r githash=$5 local -r latestpath=$6 echo "$githash" >> "$artifactspath"/githash # Upload artifacts to s3 # 1. To proper path on s3 with buildId-githash # 2. Latest path to indicate the latest build, with --delete option to delete stale files in the dest path aws s3 sync "$artifactspath" "$artifactsbucket"/"$projectpath"/"$buildidentifier"-"$githash"/artifacts --acl public-read aws s3 sync "$artifactspath" "$artifactsbucket"/"$projectpath"/"$latestpath" --delete --acl public-read } function build::gather_licenses() { # force 1.16 since thats the version used to install go-licenses in builder-base build::common::use_go_version 1.18 if ! command -v go-licenses &> /dev/null then echo " go-licenses not found. If you need license or attribtuion file handling" echo " please refer to the doc in docs/development/attribution-files.md" exit fi local -r outputdir=$1 local -r patterns=$2 # Force deps to only be pulled form vendor directories # this is important in a couple cases where license files # have to be manually created export GOFLAGS=-mod=vendor # force platform to be linux to ensure all deps are picked up export GOOS=linux export GOARCH=amd64 mkdir -p "${outputdir}/attribution" # attribution file generated uses the output go-deps and go-license to gather the neccessary # data about each dependency to generate the amazon approved attribution.txt files # go-deps is needed for module versions # go-licenses are all the dependencies found from the module(s) that were passed in via patterns go list -deps=true -json ./... | jq -s '' > "${outputdir}/attribution/go-deps.json" go-licenses save --force $patterns --save_path="${outputdir}/LICENSES" # go-licenses can be a bit noisy with its output and lot of it can be confusing # the following messags are safe to ignore since we do not need the license url for our process NOISY_MESSAGES="cannot determine URL for|Error discovering URL|unsupported package host" go-licenses csv $patterns > "${outputdir}/attribution/go-license.csv" 2> >(grep -vE "$NOISY_MESSAGES" >&2) if cat "${outputdir}/attribution/go-license.csv" | grep -q "^vendor\/golang.org\/x"; then echo " go-licenses created a file with a std golang package (golang.org/x/*)" echo " prefixed with vendor/. This most likely will result in an error" echo " when generating the attribution file and is probably due to" echo " to a version mismatch between the current version of go " echo " and the version of go that was used to build go-licenses" exit 1 fi if cat "${outputdir}/attribution/go-license.csv" | grep -e ",LGPL-" -e ",GPL-"; then echo " one of the dependencies is licensed as LGPL or GPL" echo " which is prohibited at Amazon" echo " please look into removing the dependency" fi # go-license is pretty eager to copy src for certain license types # when it does, it applies strange permissions to the copied files # which makes deleting them later awkward # this behavior may change in the future with the following PR # https://github.com/google/go-licenses/pull/28 chmod -R 777 "${outputdir}/LICENSES" # most of the packages show up the go-license.csv file as the module name # from the go.mod file, storing that away since the source dirs usually get deleted MODULE_NAME=$(go mod edit -json | jq -r '.Module.Path') echo $MODULE_NAME > ${outputdir}/attribution/root-module.txt } function build::generate_attribution(){ local -r golang_verson=$1 local -r output_directory=${2:-"_output"} local -r attribution_file=${3:-"ATTRIBUTION.txt"} local -r root_module_name=$(cat ${output_directory}/attribution/root-module.txt) local -r go_path=$(build::common::get_go_path $golang_verson) local -r golang_version_tag=$($go_path/go version | grep -o "go[0-9].* ") if cat "${output_directory}/attribution/go-license.csv" | grep -e ",LGPL-" -e ",GPL-"; then echo " one of the dependencies is licensed as LGPL or GPL" echo " which is prohibited at Amazon" echo " please look into removing the dependency" exit 1 fi generate-attribution $root_module_name "./" $golang_version_tag $output_directory cp -f "${output_directory}/attribution/ATTRIBUTION.txt" $attribution_file } function build::common::remove_go_path() { # This is the path where the specific go binary versions reside in our builder-base image export PATH=$(echo "$PATH" | sed -e "s/^\/go\/go[0-9\.]*\/bin://") # This is the path that will most likely be correct if running locally local -r quoted_go_path=$(build::common::re_quote $GOPATH) export PATH=$(echo "$PATH" | sed -e "s/^$quoted_go_path\/go[0-9\.]*\/bin://") } function build::common::get_go_path() { local -r version=$1 # This is the path where the specific go binary versions reside in our builder-base image local -r gorootbinarypath="/go/go${version}/bin" # This is the path that will most likely be correct if running locally local -r gopathbinarypath="$GOPATH/go${version}/bin" if [ -d "$gorootbinarypath" ]; then echo $gorootbinarypath elif [ -d "$gopathbinarypath" ]; then echo $gopathbinarypath else # not in builder-base, probably running in dev environment # return default go installation local -r which_go=$(which go) echo "$(dirname $which_go)" fi } function build::common::use_go_version() { local -r version=$1 local -r gobinarypath=$(build::common::get_go_path $version) echo "Adding $gobinarypath to PATH" # Adding to the beginning of PATH to allow for builds on specific version if it exists export PATH=${gobinarypath}:$PATH } function build::common::re_quote() { local -r to_escape=$1 sed 's/[][()\.^$\/?*+]/\\&/g' <<< "$to_escape" }