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

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../" && pwd -P)"
LATEST_RELEASE_BRANCH=''
PROD_DOMAIN="distro.eks.amazonaws.com"
DEV_DOMAIN="eks-d-postsubmit-artifacts.s3.us-west-2.amazonaws.com"
declare -A RELEASE_YAML=()

function build::eksd_releases::load_release_yaml() {
    local -r release_branch=$1
    local -r echo=${2-true}
    oldopt=$-
    set +o nounset
    set +x

    # if key exists, 1 is returned which would resolve to true
    if [ ! ${RELEASE_YAML[$release_branch]+1} ]; then
        local -r yaml_url=$(build::eksd_releases::get_release_yaml_url ${release_branch})
        RELEASE_YAML[$release_branch]=$(curl -s --retry 5 $yaml_url)
    fi
    if $echo; then
        echo "${RELEASE_YAML[$release_branch]}"
    fi
    set -$(echo $oldopt | sed 's/c//') # remove -c from options for when this is invoked with bash -c
}

function build::eksd_releases::get_release_yaml_url() {
    local -r release_branch=$1
    local -r release_number=$(yq e ".releases[] | select(.branch==\"${release_branch}\").number" ${REPO_ROOT}/EKSD_LATEST_RELEASES)
    local -r dev=$(yq e ".releases[] | select(.branch==\"${release_branch}\").dev" ${REPO_ROOT}/EKSD_LATEST_RELEASES)
    local -r yaml_path="kubernetes-${release_branch}/kubernetes-${release_branch}-eks-${release_number}.yaml"
    local yaml_url="https://$PROD_DOMAIN/$yaml_path"
    if [[ $dev == "true" ]]; then
      yaml_url="https://$DEV_DOMAIN/$yaml_path"
    fi
    echo "$yaml_url"
}

function build::eksd_releases::get_release_branch() {
    if [ -z $LATEST_RELEASE_BRANCH ]; then
        LATEST_RELEASE_BRANCH=$(yq e ".latest" ${REPO_ROOT}/EKSD_LATEST_RELEASES)
    fi
    echo $LATEST_RELEASE_BRANCH
}

function build::eksd_releases::get_eksd_release_number() {
    local -r release_branch=$1

    oldopt=$-
    set +x

    local -r yaml=$(build::eksd_releases::load_release_yaml $release_branch)

    echo "$yaml" |  yq e ".spec.number" -

    set -$oldopt
}

function build::eksd_releases::get_eksd_release_name() {
    local -r release_branch=$1

    oldopt=$-
    set +x

    local -r yaml=$(build::eksd_releases::load_release_yaml $release_branch)

    echo "$yaml" |  yq e ".metadata.name" -

    set -$oldopt
}

function build::eksd_releases::get_eksd_component_version() {
    local -r component=$1
    local -r release_branch=$2

    oldopt=$-
    set +x

    local -r yaml=$(build::eksd_releases::load_release_yaml $release_branch)

    echo "$yaml" | yq e ".status.components[] | select(.name == \"$component\") .gitTag" -

    set -$oldopt
}

function build::eksd_releases::get_eksd_component_asset_path() {
    local -r component=$1
    local -r release_branch=$2
    local -r path=$3
    local -r arch=$4
    local -r asset=${5-}

    oldopt=$-
    set +x

    local -r yaml=$(build::eksd_releases::load_release_yaml $release_branch)

    local query=".status.components[] | select(.name == \"$component\") .assets[]"

    if [[ $path == ".archive.uri" ]] || [[ $path == ".archive.sha256" ]]; then
        query+=" | select(.type == \"Archive\")"
    fi

    if [ -z $asset ]; then
        query+=" | select(.arch[0] == \"$arch\") $path"
    else
        query+=" | select(.name == \"$asset\") | select(.arch[0] == \"$arch\") $path"
    fi

    echo "$yaml" | yq e "$query" -

    set -$(echo $oldopt | sed 's/c//') # remove -c from options for when this is invoked with bash -c
}

function build::eksd_releases::get_eksd_component_asset_url() {
    local -r component=$1
    local -r asset=$2
    local -r release_branch=${3-$(build::eksd_releases::get_release_branch)}
    local -r arch=${4-amd64}

    build::eksd_releases::get_eksd_component_asset_path $component $release_branch ".archive.uri" $arch $asset
}

function build::eksd_releases::get_eksd_component_asset_sha() {
    local -r component=$1
    local -r asset=$2
    local -r release_branch=${3-$(build::eksd_releases::get_release_branch)}
    local -r arch=${4-amd64}

    build::eksd_releases::get_eksd_component_asset_path $component $release_branch ".archive.sha256" $arch $asset
}

function build::eksd_releases::get_eksd_kubernetes_asset_url() {
    local -r asset=$1
    local -r release_branch=${2-$(build::eksd_releases::get_release_branch)}
    local -r arch=${3-amd64}

    build::eksd_releases::get_eksd_component_asset_url "kubernetes" $asset $release_branch $arch
}

function build::eksd_releases::get_eksd_kubernetes_image_url() {
    local -r asset=$1
    local -r release_branch=${2-$(build::eksd_releases::get_release_branch)}
    local -r arch=${3-amd64}

    build::eksd_releases::get_eksd_component_asset_path "kubernetes" $release_branch ".image.uri" $arch $asset
}

function build::eksd_releases::get_eksd_component_asset_image_tag() {
    local -r component=$1
    local -r asset=$2
    local -r release_branch=$3
    local -r arch=${4-amd64}

    build::eksd_releases::get_eksd_component_asset_path $component $release_branch ".image.uri" $arch $asset | awk -F: '{print $2}'
}

function build::eksd_releases::get_eksd_component_url() {
    local -r component=$1
    local -r release_branch=${2-$(build::eksd_releases::get_release_branch)}
    local -r arch=${3-amd64}

    build::eksd_releases::get_eksd_component_asset_path $component $release_branch ".archive.uri" $arch
}

function build::eksd_releases::get_eksd_component_sha() {
    local -r component=$1
    local -r release_branch=${2-$(build::eksd_releases::get_release_branch)}
    local -r arch=${3-amd64}

    build::eksd_releases::get_eksd_component_asset_path $component $release_branch ".archive.sha256" $arch
}

function build::eksd_releases::get_eksd_image_repo() {
    local -r release_branch=${1-$(build::eksd_releases::get_release_branch)}

    build::eksd_releases::get_eksd_kubernetes_image_url "kube-apiserver-image" $release_branch | sed -E 's,/kubernetes/kube-apiserver.*,,'
}

function build::eksd_releases::get_eksd_kubernetes_asset_base_url() {
    local -r release_branch=${1-$(build::eksd_releases::get_release_branch)}

    local -r kube_version=$(build::eksd_releases::get_eksd_component_version "kubernetes" $release_branch)
    local -r apiserver="bin/linux/amd64/kube-apiserver"
    build::eksd_releases::get_eksd_kubernetes_asset_url $apiserver $release_branch | sed -E "s,/$kube_version/$apiserver.*,,"
}

function build::eksd_releases::get_eksd_cni_asset_base_url() {
    local -r release_branch=${1-$(build::eksd_releases::get_release_branch)}

    local -r cni_plugins_version=$(build::eksd_releases::get_eksd_component_version "cni-plugins" $release_branch)
    build::eksd_releases::get_eksd_component_url "cni-plugins" $release_branch | sed -E "s,/$cni_plugins_version/cni-plugins.*,,"
}


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

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

BINARY_DEPS_DIR="$1"
DEP="$2"
ARTIFACTS_BUCKET="$3"
LATEST_TAG="$4"
RELEASE_BRANCH="${5-$(build::eksd_releases::get_release_branch)}"

DEP=${DEP#"$BINARY_DEPS_DIR"}
OS_ARCH="$(cut -d '/' -f1 <<< ${DEP})"
PRODUCT=$(cut -d '/' -f2 <<< ${DEP})
REPO_OWNER=$(cut -d '/' -f3 <<< ${DEP})
REPO=$(cut -d '/' -f4 <<< ${DEP})

RELEASE_BRANCH_OVERRIDE=$(cut -d '/' -f5 <<< ${DEP})
RELEASE_BRANCH=${RELEASE_BRANCH_OVERRIDE:-$RELEASE_BRANCH}

ARCH="$(cut -d '-' -f2 <<< ${OS_ARCH})"
CODEBUILD_CI="${CODEBUILD_CI:-false}"

OUTPUT_DIR_FILE=$BINARY_DEPS_DIR/linux-$ARCH/$PRODUCT/$REPO_OWNER/$REPO

if [[ -n "$RELEASE_BRANCH_OVERRIDE" ]]; then
    OUTPUT_DIR_FILE+=/$RELEASE_BRANCH_OVERRIDE
fi

if [[ $REPO == *.tar.gz ]]; then
    mkdir -p $(dirname $OUTPUT_DIR_FILE)
else
    mkdir -p $OUTPUT_DIR_FILE
fi

if [[ $PRODUCT = 'eksd' ]]; then
    if [[ $REPO_OWNER = 'kubernetes' ]]; then
        TARBALL="kubernetes-$REPO-linux-$ARCH.tar.gz"
        URL=$(build::eksd_releases::get_eksd_kubernetes_asset_url $TARBALL $RELEASE_BRANCH $ARCH)
        # these tarballs will extra with the kubernetes/{client,server} folders
        OUTPUT_DIR_FILE=$BINARY_DEPS_DIR/linux-$ARCH/$PRODUCT
    else
        URL=$(build::eksd_releases::get_eksd_component_url $REPO_OWNER $RELEASE_BRANCH $ARCH)
    fi
else
    URL=$(build::common::get_latest_eksa_asset_url $ARTIFACTS_BUCKET $REPO_OWNER/$REPO $ARCH $LATEST_TAG $RELEASE_BRANCH)
fi

if [ "$CODEBUILD_CI" = "true" ]; then
    build::common::echo_and_run build::common::wait_for_tarball $URL
fi

DOWNLOAD_DIR=$(mktemp -d)
trap "rm -rf $DOWNLOAD_DIR" EXIT

build::common::echo_and_run wget -q --retry-connrefused $URL $URL.sha256 -P $DOWNLOAD_DIR
(cd $DOWNLOAD_DIR && sha256sum -c *.sha256)

if [[ $REPO == *.tar.gz ]]; then
    build::common::echo_and_run mv $DOWNLOAD_DIR/*.tar.gz $OUTPUT_DIR_FILE
else
    build::common::echo_and_run tar xzf $DOWNLOAD_DIR/*.tar.gz -C $OUTPUT_DIR_FILE
fi


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

set -o errexit
set -o nounset
set -o pipefail

REPO="$1"
OUTPUT_DIR="$2"
PACKAGE_FILTER="$3"
REPO_SUBPATH="${4:-}"
GOLANG_VERSION="${5:-}"
LICENSE_THRESHOLD="${6:-}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

cd $REPO/$REPO_SUBPATH
build::gather_licenses $OUTPUT_DIR "$PACKAGE_FILTER" "$GOLANG_VERSION" "$LICENSE_THRESHOLD"


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

set -o errexit
set -o nounset
set -o pipefail

PROJECT="$1"
GIT_TAG="$2"
OUTPUT_DIR="$3"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

build::non-golang::gather_licenses $PROJECT $GIT_TAG $OUTPUT_DIR


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

set -o errexit
set -o nounset
set -o pipefail

PROJECT_ROOT="$1"
BINARY_TARGET_FILES="$2"
BINARY_PLATFORMS="$3"
BINARY_TARGETS="$4"
REPO="$5"
HAS_PATCHES="$6"
LOCAL_IMAGE_TARGETS="$7"
IMAGE_TARGETS="$8"
BUILD_TARGETS="$9"
RELEASE_TARGETS="${10}"
HAS_S3_ARTIFACTS="${11}"
HAS_LICENSES="${12}"
REPO_NO_CLONE="${13}"
FETCH_BINARIES_TARGETS="${14}"
HAS_HELM_CHART="${15}"
IN_DOCKER_TARGETS="${16}"

NL=$'\n'
HEADER="########### DO NOT EDIT #############################"
FOOTER="########### END GENERATED ###########################"

MAKEFILE=$PROJECT_ROOT/Makefile
HELPFILE=$PROJECT_ROOT/Help.mk

SED=sed
if [ "$(uname -s)" = "Darwin" ]; then
    SED=gsed
fi

$SED -i "/$HEADER/,/$FOOTER/d" $MAKEFILE
# remove trailing newlines
printf %s "$(< $MAKEFILE)" > $MAKEFILE

touch $HELPFILE

$SED -i "/$HEADER/,/$FOOTER/d" $HELPFILE
# remove trailing newlines
printf %s "$(< $HELPFILE)" > $HELPFILE

# Generate help items from Common.mk
EXTRA_HELP="$(make help-list --no-print-directory)"
BINARY_TARGETS_HELP=""
CHECKSUMS_TARGETS_HELP=""
if [ ! -z "$(echo "$BINARY_TARGETS" | xargs)" ]; then
    BINARY_TARGETS_HELP+="${NL}${NL}##@ Binary Targets"
    BINARY_TARGETS_HELP+="${NL}binaries: ## Build all binaries: \`${BINARY_TARGET_FILES}\` for \`${BINARY_PLATFORMS}\`"
    TARGETS=(${BINARY_TARGETS// / })
    for target in "${TARGETS[@]}"; do
        BINARY_TARGETS_HELP+="${NL}${target}: ## Build \`${target}\`"
    done

    CHECKSUMS_TARGETS_HELP+="${NL}${NL}##@ Checksum Targets"
    CHECKSUMS_TARGETS_HELP+="${NL}checksums: ## Update checksums file based on currently built binaries."
    CHECKSUMS_TARGETS_HELP+="${NL}validate-checksums: # Validate checksums of currently built binaries against checksums file."
    CHECKSUMS_TARGETS_HELP+="${NL}all-checksums: ## Update checksums files for all RELEASE_BRANCHes."
fi

GIT_TARGETS_HELP=""
if [[ "$REPO_NO_CLONE" != "true" ]]; then
    GIT_TARGETS_HELP+="${NL}${NL}##@ GIT/Repo Targets"
    GIT_TARGETS_HELP+="${NL}clone-repo:  ## Clone upstream \`${REPO}\`"
    GIT_TARGETS_HELP+="${NL}checkout-repo: ## Checkout upstream tag based on value in GIT_TAG file"
fi

PATCHES_TARGET=""
if [[ "$HAS_PATCHES" == "true" ]]; then
    PATCHES_TARGET+="${NL}patch-repo: ## Patch upstream repo with patches in patches directory"
fi

IMAGE_TARGETS_HELP=""
if [ ! -z "$(echo "$LOCAL_IMAGE_TARGETS" | xargs)" ]; then
    IMAGE_TARGETS_HELP+="${NL}${NL}##@ Image Targets"
    IMAGE_TARGETS_HELP+="${NL}local-images: ## Builds \`$(echo ${LOCAL_IMAGE_TARGETS} | xargs)\` as oci tars for presumbit validation"
    IMAGE_TARGETS_HELP+="${NL}images: ## Pushes \`$(echo ${IMAGE_TARGETS} | xargs)\` to IMAGE_REPO"

    ALL_IMAGES=()
    TARGETS=(${LOCAL_IMAGE_TARGETS// / })
    for target in "${TARGETS[@]}"; do
        ALL_IMAGES+=("$target")
    done
    TARGETS=(${IMAGE_TARGETS// / })
    for target in "${TARGETS[@]}"; do
        if [[ ! " ${ALL_IMAGES[*]} " =~ " ${target} " ]]; then
            ALL_IMAGES+=("$target")
        fi
    done
    for image in "${ALL_IMAGES[@]}"; do
        IMAGE_TARGETS_HELP+="${NL}$image: ## Builds/pushes \`${image}\`"
    done

fi

ARTIFACTS_TARGETS=""
if [[ "$HAS_S3_ARTIFACTS" == "true" ]]; then
    ARTIFACTS_TARGETS+="${NL}${NL}##@ Artifact Targets"
    ARTIFACTS_TARGETS+="${NL}tarballs: ## Create tarballs by calling build/lib/simple_create_tarballs.sh unless SIMPLE_CREATE_TARBALLS=false, then tarballs must be defined in project Makefile"
    ARTIFACTS_TARGETS+="${NL}s3-artifacts: # Prepare ARTIFACTS_PATH folder structure with tarballs/manifests/other items to be uploaded to s3"
    ARTIFACTS_TARGETS+="${NL}upload-artifacts: # Upload tarballs and other artifacts from ARTIFACTS_PATH to S3"
fi

LICENSES_TARGETS=""
if [[ "$HAS_LICENSES" == "true" ]]; then
    LICENSES_TARGETS+="${NL}${NL}##@ License Targets"
    LICENSES_TARGETS+="${NL}gather-licenses: ## Helper to call \$(GATHER_LICENSES_TARGETS) which gathers all licenses"
    LICENSES_TARGETS+="${NL}attribution: ## Generates attribution from licenses gathered during \`gather-licenses\`."
    LICENSES_TARGETS+="${NL}attribution-pr: ## Generates PR to update attribution files for projects"
    LICENSES_TARGETS+="${NL}attribution-checksums: ## Update attribution and checksums files."
    LICENSES_TARGETS+="${NL}all-attributions: ## Update attribution files for all RELEASE_BRANCHes."
    LICENSES_TARGETS+="${NL}all-attributions-checksums: ## Update attribution and checksums files for all RELEASE_BRANCHes."
fi

CLEAN_TARGETS="${NL}${NL}##@ Clean Targets"
CLEAN_TARGETS+="${NL}clean: ## Removes source and _output directory"
if [[ "$REPO_NO_CLONE" != "true" ]]; then
    CLEAN_TARGETS+="${NL}clean-repo: ## Removes source directory"
fi

FETCH_BINARY_TARGETS_HELP=""
if [ ! -z "$(echo "$FETCH_BINARIES_TARGETS" | xargs)" ]; then
    FETCH_BINARY_TARGETS_HELP+="${NL}${NL}##@ Fetch Binary Targets"
    TARGETS=(${FETCH_BINARIES_TARGETS// / })
    for target in "${TARGETS[@]}"; do
        FETCH_BINARY_TARGETS_HELP+="${NL}${target}: ## Fetch \`${target}\`"
    done
fi

HELM_TARGETS=""
if [[ "$HAS_HELM_CHART" == "true" ]]; then
    HELM_TARGETS+="${NL}${NL}##@ Helm Targets"
    HELM_TARGETS+="${NL}helm/build: ## Build helm chart"
    HELM_TARGETS+="${NL}helm/push: ## Build helm chart and push to registry defined in IMAGE_REPO."
fi

TARGETS=(${IN_DOCKER_TARGETS// / })
DOCKER_TARGETS="${NL}${NL}##@ Run in Docker Targets"
for target in "${TARGETS[@]}"; do
    DOCKER_TARGETS+="${NL}run-${target}-in-docker: ## Run \`${target}\` in docker builder container"
done

cat >> $HELPFILE << EOF
${NL}${NL}${NL}${HEADER}
# To update call: make add-generated-help-block
# This is added to help document dynamic targets and support shell autocompletion
${GIT_TARGETS_HELP}${PATCHES_TARGET}${BINARY_TARGETS_HELP}${IMAGE_TARGETS_HELP}${HELM_TARGETS}${FETCH_BINARY_TARGETS_HELP}${CHECKSUMS_TARGETS_HELP}${DOCKER_TARGETS}${ARTIFACTS_TARGETS}${LICENSES_TARGETS}${CLEAN_TARGETS}
${EXTRA_HELP}

##@ Build Targets
build: ## Called via prow presubmit, calls \`${BUILD_TARGETS//$PROJECT_ROOT\//""}\`
release: ## Called via prow postsubmit + release jobs, calls \`${RELEASE_TARGETS}\`
${FOOTER}
EOF

cat >> $MAKEFILE << EOF
${NL}${NL}${NL}${HEADER}
# To update call: make add-generated-help-block
# This is added to help document dynamic targets and support shell autocompletion
# Run make help for a formatted help block with all targets
include Help.mk
${FOOTER}
EOF


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

set -o errexit
set -o pipefail

BASE_DIRECTORY="${1?Specify first argument - Base directory of build-tooling repo}"
UPSTREAM_PROJECTS_FILE="$BASE_DIRECTORY/UPSTREAM_PROJECTS.yaml"

YQ_LATEST_RELEASE_URL="https://github.com/mikefarah/yq/releases/latest"
CURRENT_YQ_VERSION=$(yq -V | awk '{print $NF}')
CURRENT_YQ_MAJOR_VERSION=${CURRENT_YQ_VERSION:1:1}
LATEST_YQ_VERSION=$(curl --retry 5 -fIsS $YQ_LATEST_RELEASE_URL | grep "location:" | awk -F/ '{print $NF}')
LATEST_YQ_MAJOR_VERSION=${LATEST_YQ_VERSION:1:1}
if [ $CURRENT_YQ_MAJOR_VERSION -lt $LATEST_YQ_MAJOR_VERSION ]; then
    echo "Current yq major version v$CURRENT_YQ_MAJOR_VERSION.x is older than the latest (v$LATEST_YQ_MAJOR_VERSION.x)."
    echo "Please install the latest version of yq from $YQ_LATEST_RELEASE_URL"
    exit 1
fi

MAKE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"

cd $MAKE_ROOT

declare -i org_count=0 # Counter variable for each org

yq eval --null-input ".projects = []" > $UPSTREAM_PROJECTS_FILE # Creates an empty YAML array

# Iterating over orgs under projects folder
for org_path in projects/*; do
    repos=() # Empty array for repos in the org
    org=$(cut -d/ -f2 <<< $org_path)
    declare -i repo_count=0
    for repo_path in projects/$org/*; do
        repo="$(cut -d/ -f3 <<< $repo_path)"
        if [ "$org" = "aws" ] & [[ $repo =~ "eks-anywhere" ]]; then # Ignore self-referential repos
            continue
        fi
        if [ "$org" = "kubernetes-sigs" ] & [[ "$repo" =~ "metrics-server" ]]; then # Ignore helm builds backed by eks-d images to reduce toil
            continue
        fi
        if curl --retry 5 -fIsS https://github.com/$org/$repo &> /dev/null; then # Check if org/repo combination is a Github repo
            repos+=("$repo")
        fi
    done
    if [ ${#repos[@]} -gt 0 ]; then
        yq eval -i -P ".projects += [{\"org\": \"$org\", \"repos\": []}]" $UPSTREAM_PROJECTS_FILE # Add an entry for this org in the projects array
        for repo in "${repos[@]}"; do
            yq eval -i -P ".projects[$org_count].repos += [{\"name\": \"$repo\", \"versions\": []}]" $UPSTREAM_PROJECTS_FILE # Add each repo to the repos array
            git_tags=$(find projects/$org/$repo -type f -name "GIT_TAG" | sort)
            for file in $git_tags; do
                tag=$(cat $file)
                if [ $repo = "cilium" ]; then
                    yq eval -i -P ".projects[$org_count].repos[$repo_count].versions += [{\"tag\": \"$tag\"}]" $UPSTREAM_PROJECTS_FILE
                else
                    if [ "$(git ls-remote --tags https://github.com/$org/$repo | awk '{print $2}' | grep $tag || true)" ]; then
                        yq eval -i -P ".projects[$org_count].repos[$repo_count].versions += [{\"tag\": \"$tag\"}]" $UPSTREAM_PROJECTS_FILE
                    else
                        yq eval -i -P ".projects[$org_count].repos[$repo_count].versions += [{\"commit\": \"$tag\"}]" $UPSTREAM_PROJECTS_FILE
                    fi
                fi
            done
            repo_count+=1
        done
        org_count+=1
    fi
done

HEAD_COMMENT=$(cat $BASE_DIRECTORY/hack/boilerplate.yq.txt)
yq eval -i ". headComment=\"$HEAD_COMMENT\"" $UPSTREAM_PROJECTS_FILE # Add a header comment with license verbiage and no-edit warning


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

set -o errexit
set -o nounset
set -o pipefail

BASE_DIRECTORY="${1?Specify first argument - Base directory of build-tooling repo}"
ALL_PROJECTS="${2?Specify second argument - All projects in repo}"
STAGING_BUILDSPEC_FILE="${3}"
SKIP_DEPEND_ON="${4:-false}"
EXCLUDE_VAR="${5:-EXCLUDE_FROM_STAGING_BUILDSPEC}"
BUILDSPECS_VAR="${6:-BUILDSPECS}"
FAST_FAIL="${7:-true}"
ADD_FINAL_STAGE="${8:-}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

YQ_LATEST_RELEASE_URL="https://github.com/mikefarah/yq/releases/latest"
CURRENT_YQ_VERSION=$(yq -V | awk '{print $NF}')
CURRENT_YQ_MAJOR_VERSION=${CURRENT_YQ_VERSION:1:1}
LATEST_YQ_VERSION=$(curl -fIsS $YQ_LATEST_RELEASE_URL | grep "location:" | awk -F/ '{print $NF}')
LATEST_YQ_MAJOR_VERSION=${LATEST_YQ_VERSION:1:1}
if [ $CURRENT_YQ_MAJOR_VERSION -lt $LATEST_YQ_MAJOR_VERSION ]; then
    echo "Current yq major version v$CURRENT_YQ_MAJOR_VERSION.x is older than the latest (v$LATEST_YQ_MAJOR_VERSION.x)."
    echo "Please install the latest version of yq from $YQ_LATEST_RELEASE_URL"
    exit 1
fi

MAKE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"

cd $MAKE_ROOT

mkdir -p $(dirname $STAGING_BUILDSPEC_FILE)
yq eval --null-input ".batch={\"fast-fail\":$FAST_FAIL,\"build-graph\":[]}" > $STAGING_BUILDSPEC_FILE # Creates an empty YAML array

# TODO: refactor use of release_branch to get git_tag and golang_version in makefile, we should be able to push this to common.mk and avoid needing to pass it here
RELEASE_BRANCH=$(build::eksd_releases::get_release_branch)

function make_var() {
    make --no-print-directory -C $1 "$(echo "$2" | sed 's/[^ ]* */var-value-&/g')" CODEBUILD_CI=true 2>/dev/null
}

PROJECTS=(${ALL_PROJECTS// / })
ALL_PROJECT_IDS=""
for project in "${PROJECTS[@]}"; do
    org=$(cut -d_ -f1 <<< $project)
    repo=$(cut -d_ -f2- <<< $project)

    PROJECT_PATH=$MAKE_ROOT/projects/$org/$repo

    if [[ "true" == "$(make_var $PROJECT_PATH $EXCLUDE_VAR)" ]]; then
        continue
    fi

    CLONE_URL=""
    if [[ "true" != "$(make_var $PROJECT_PATH REPO_NO_CLONE)" ]]; then
        REPO=$(make_var $PROJECT_PATH CLONE_URL AWS_REGION=us-west-2)
        CLONE_URL=",\"CLONE_URL\":\"$REPO\""
    fi

    BUILDSPECS=$(make_var $PROJECT_PATH $BUILDSPECS_VAR)
    SPECS=(${BUILDSPECS// / })
    for (( i=0; i < ${#SPECS[@]}; i++ )); do
        IDENTIFIER="${org//-/_}_${repo//-/_}"

        buildspec=${SPECS[$i]}

        DEPEND_ON=""
        # something other than empty string since some overrides are empty strings
        PROJECT_DEPENDENCIES="false"
        for var in "BUILDSPEC_$((( $i + 1 )))_DEPENDS_ON_OVERRIDE" "BUILDSPEC_DEPENDS_ON_OVERRIDE"; do
            BUILDSPEC_DEPENDS_ON="$(make_var $PROJECT_PATH $var)"
            HARDCODED_DEP="false"
            if [[ "none" = "$BUILDSPEC_DEPENDS_ON" ]]; then
                PROJECT_DEPENDENCIES=""
                break
            elif [[ -n "$BUILDSPEC_DEPENDS_ON" ]]; then
                HARDCODED_DEP="true"
                PROJECT_DEPENDENCIES=$BUILDSPEC_DEPENDS_ON
                break
            fi
        done

        BUILDSPEC_IDENTIFIER_OVERRIDE="$(make_var $PROJECT_PATH BUILDSPEC_$((( $i + 1 )))_IDENTIFIER_OVERRIDE)"
        if [[ -n "$BUILDSPEC_IDENTIFIER_OVERRIDE" ]]; then
            IDENTIFIER="$BUILDSPEC_IDENTIFIER_OVERRIDE"
        fi

        echo "Adding: $IDENTIFIER"

        if [ "$PROJECT_DEPENDENCIES" = "false" ]; then
            PROJECT_DEPENDENCIES=$(make_var $PROJECT_PATH PROJECT_DEPENDENCIES)
        fi

        if [ -n "$PROJECT_DEPENDENCIES" ] && [ "$SKIP_DEPEND_ON" != "true" ]; then
            DEPS=(${PROJECT_DEPENDENCIES// / })
            for dep in "${DEPS[@]}"; do
                if [ "$HARDCODED_DEP" = "true" ]; then
                    DEPEND_ON+="\"$dep\","
                    continue
                fi

                DEP_PRODUCT="$(cut -d/ -f1 <<< $dep)"
                if [[ "$DEP_PRODUCT" == "eksd" ]]; then
                    continue
                fi
                DEP_ORG="$(cut -d/ -f2 <<< $dep)"
                DEP_REPO="$(cut -d/ -f3 <<< $dep)"
                DEPEND_ON+="\"${DEP_ORG//-/_}_${DEP_REPO//-/_}\","

                if [ ! -d $MAKE_ROOT/projects/$DEP_ORG/$DEP_REPO ]; then
                    echo "Non-existent project dependency: $dep!!!"
                    exit 1
                fi
            done
        fi

        if [ -n "$DEPEND_ON" ]; then
            DEPEND_ON="\"depend-on\":[${DEPEND_ON%?}],"
        fi
        BUILDSPEC_VARS_KEYS=$(make_var $PROJECT_PATH BUILDSPEC_VARS_KEYS)
        if [[ -z "$BUILDSPEC_VARS_KEYS" ]]; then
            BUILDSPEC_VARS_KEYS=$(make_var $PROJECT_PATH BUILDSPEC_$((( $i + 1 )))_VARS_KEYS)
        fi

        BUILDSPEC_PLATFORM=$(make_var $PROJECT_PATH BUILDSPEC_$((( $i + 1 )))_PLATFORM)
        if [[ -z "$BUILDSPEC_PLATFORM" ]]; then
            BUILDSPEC_PLATFORM=$(make_var $PROJECT_PATH BUILDSPEC_PLATFORM)
        fi

        BUILDSPEC_COMPUTE_TYPE=$(make_var $PROJECT_PATH BUILDSPEC_$((( $i + 1 )))_COMPUTE_TYPE)
        if [[ -z "$BUILDSPEC_COMPUTE_TYPE" ]]; then
            BUILDSPEC_COMPUTE_TYPE=$(make_var $PROJECT_PATH BUILDSPEC_COMPUTE_TYPE)
        fi

        ARCH_TYPE="\"type\":\"$BUILDSPEC_PLATFORM\",\"compute-type\":\"$BUILDSPEC_COMPUTE_TYPE\","

        if [[ "$BUILDSPECS_VAR" == "CHECKSUMS_BUILDSPECS" ]] && [[ "$BUILDSPEC_VARS_KEYS" == "RELEASE_BRANCH" ]] && [[ "false" == "$(make_var $PROJECT_PATH BINARIES_ARE_RELEASE_BRANCHED)" ]]; then
            BUILDSPEC_VARS_KEYS=""
        fi

        if [[ -n "$BUILDSPEC_VARS_KEYS" ]]; then
            KEYS=(${BUILDSPEC_VARS_KEYS// / })

            BUILDSPEC_VARS_VALUES=$(make_var $PROJECT_PATH BUILDSPEC_VARS_VALUES)
            if [[ -z "$BUILDSPEC_VARS_VALUES" ]]; then
                BUILDSPEC_VARS_VALUES=$(make_var $PROJECT_PATH BUILDSPEC_$((( $i + 1 )))_VARS_VALUES)
            fi
            VARS=(${BUILDSPEC_VARS_VALUES// / })

            # Note: only support 1 or 2 vars for now since that is all we need for kind + image-builder
            if [ ${#VARS[@]} -eq 1 ]; then
                VALUES_1=$(make_var $PROJECT_PATH ${VARS[0]})
                ARR_1=(${VALUES_1// / })

                for val1 in "${ARR_1[@]}"; do
                    BUILDSPEC_NAME=$(basename $buildspec .yml)
                    IDENTIFIER=${org//-/_}_${repo//-/_}_${val1//[-\/]/_}

                    # If building on one binary platform assume we want to run on a specific arch instance
                    ARCH_TYPE="\"type\":\"$BUILDSPEC_PLATFORM\",\"compute-type\":\"$BUILDSPEC_COMPUTE_TYPE\","
                    if [ "${KEYS[0]}" = "BINARY_PLATFORMS" ]; then
                        if [ "${val1}" = "linux/amd64" ]; then
                            ARCH_TYPE="\"type\":\"LINUX_CONTAINER\",\"compute-type\":\"BUILD_GENERAL1_SMALL\","
                        else
                            ARCH_TYPE="\"type\":\"ARM_CONTAINER\",\"compute-type\":\"BUILD_GENERAL1_SMALL\","
                        fi
                    fi

                    ALL_PROJECT_IDS+="\"$IDENTIFIER\","
                    yq eval -i -P \
                        ".batch.build-graph += [{\"identifier\":\"$IDENTIFIER\",\"buildspec\":\"$buildspec\",$DEPEND_ON\"env\":{$ARCH_TYPE\"variables\":{\"PROJECT_PATH\": \"projects/$org/$repo\"$CLONE_URL,\"${KEYS[0]}\":\"$val1\"}}}]" \
                        $STAGING_BUILDSPEC_FILE
                done
            else
                VALUES_1=$(make_var $PROJECT_PATH ${VARS[0]})
                VALUES_2=$(make_var $PROJECT_PATH ${VARS[1]})

                ARR_1=(${VALUES_1// / })
                ARR_2=(${VALUES_2// / })
                for val1 in "${ARR_1[@]}"; do
                    for val2 in "${ARR_2[@]}"; do
                        BUILDSPEC_NAME=$(basename $buildspec .yml)
                        IDENTIFIER=${org//-/_}_${repo//-/_}_${val1//-/_}_${val2//-/_}_${BUILDSPEC_NAME//-/_}
                        ALL_PROJECT_IDS+="\"$IDENTIFIER\","
                        yq eval -i -P \
                            ".batch.build-graph += [{\"identifier\":\"$IDENTIFIER\",\"buildspec\":\"$buildspec\",$DEPEND_ON\"env\":{$ARCH_TYPE\"variables\":{\"PROJECT_PATH\": \"projects/$org/$repo\"$CLONE_URL,\"${KEYS[0]}\":\"$val1\",\"${KEYS[1]}\":\"$val2\"}}}]" \
                            $STAGING_BUILDSPEC_FILE
                    done
                done
            fi
        else
            ALL_PROJECT_IDS+="\"$IDENTIFIER\","
            yq eval -i -P \
                ".batch.build-graph += [{\"identifier\":\"$IDENTIFIER\",\"buildspec\":\"$buildspec\",$DEPEND_ON\"env\":{$ARCH_TYPE\"variables\":{\"PROJECT_PATH\": \"projects/$org/$repo\"$CLONE_URL}}}]" \
                $STAGING_BUILDSPEC_FILE
        fi

    done
done

if [ -n "${ADD_FINAL_STAGE}" ]; then
    ARCH_TYPE="\"type\":\"ARM_CONTAINER\",\"compute-type\":\"BUILD_GENERAL1_SMALL\""
    yq eval -i -P \
        ".batch.build-graph += [{\"identifier\":\"final_stage\",\"buildspec\":\"$ADD_FINAL_STAGE\",\"env\":{$ARCH_TYPE},\"depend-on\":[${ALL_PROJECT_IDS%?}]}]" \
        $STAGING_BUILDSPEC_FILE
fi

HEAD_COMMENT=$(cat $BASE_DIRECTORY/hack/boilerplate.yq.txt)
yq eval -i ". headComment=\"$HEAD_COMMENT\"" $STAGING_BUILDSPEC_FILE # Add a header comment with license verbiage and no-edit warning

if [[ "${#PROJECTS[@]}" = "1" ]]; then
    # if there is only one project we do not want project_path and clone_url to be set since it will be set at the codebuild level
    yq -i 'del(.batch.build-graph.[].env.variables.PROJECT_PATH)' $STAGING_BUILDSPEC_FILE
    yq -i 'del(.batch.build-graph.[].env.variables.CLONE_URL)' $STAGING_BUILDSPEC_FILE
    yq -i 'del(.. | select(tag == "!!map" and length == 0))' $STAGING_BUILDSPEC_FILE
    yq -i 'del(.. | select(tag == "!!map" and length == 0))' $STAGING_BUILDSPEC_FILE
fi


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

set -o errexit
set -o nounset
set -o pipefail

PROJECT_ROOT="$1"
REPO="$2"
TAG="$3"
GOLANG_VERSION="$4"
REPO_SUBPATH="${5:-}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

cd $REPO/$REPO_SUBPATH

CACHE_KEY=$(echo $PROJECT_ROOT | sed 's/\(.*\)\//\1-/' | xargs basename)
build::common::use_go_version $GOLANG_VERSION
build::common::set_go_cache $CACHE_KEY $TAG
build::common::echo_and_run go mod vendor


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

set -x
set -o errexit
set -o nounset
set -o pipefail

OUTPUT_DIR="${1?First arguement is output directory}"
HELM_DESTINATION_REPOSITORY="${2?Second argument is helm destination repository}"
CHART_NAME=$(basename ${HELM_DESTINATION_REPOSITORY})

#
# Build
#
cd ${OUTPUT_DIR}/helm
helm package "${CHART_NAME}"


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

set -x
set -o errexit
set -o nounset
set -o pipefail

HELM_SOURCE_REPOSITORY="${1?First argument is helm source repository}"
HELM_DESTINATION_REPOSITORY="${2?Second argument is helm destination repository}"
HELM_DIRECTORY="${3?Third argument is helm directory}"
OUTPUT_DIR="${4?Fouth arguement is output directory}"

CHART_NAME=$(basename ${HELM_DESTINATION_REPOSITORY})
DEST_DIR=${OUTPUT_DIR}/helm/${CHART_NAME}
SOURCE_DIR=$(basename ${HELM_SOURCE_REPOSITORY})/${HELM_DIRECTORY}/.

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

#
# Copy
#
mkdir -p ${DEST_DIR}
rsync -a --exclude .git "${SOURCE_DIR}" "${DEST_DIR}"
build::non-golang::copy_licenses ${HELM_SOURCE_REPOSITORY} $DEST_DIR/LICENSES/github.com/${HELM_SOURCE_REPOSITORY}


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

set -x
set -o errexit
set -o nounset
set -o pipefail

SED=sed
if [ "$(uname -s)" = "Darwin" ]; then
    SED=gsed
fi

IMAGE_REGISTRY="${1?First argument is image registry}"
HELM_REPO_URL="${2?Second arguement is update repo url}"
HELM_PULL_NAME="${3?Third argument is name of helm chart}"
REPO="${4?Fourth argument is helm source repository}"
HELM_DIRECTORY="${5?Fifth argument is helm directory name}"
CHART_VERSION="${6?Sixth argument is the version of helm chart we need to pull}"
COPY_CRDS="${7?Seventh argument is whether we need add crds to the helm chart}"

function cleanup() {
  if [ -d "$HELM_PULL_NAME" ]; then
    rm -rf "${HELM_PULL_NAME}"
  fi
}

function cleanup-chart() {
  if [ -d "${REPO}/${HELM_DIRECTORY}" ]; then
    rm -rf "${REPO}/${HELM_DIRECTORY}"
  fi
}

function copy-crds() {
  if [ -d "${COPY_CRDS}" ]; then
    rm -rf  ${REPO}/${HELM_DIRECTORY}/crds/*
    mkdir ${REPO}/${HELM_DIRECTORY}/crds || true
    cp ${COPY_CRDS}/* ${REPO}/${HELM_DIRECTORY}/crds
  fi
}

trap cleanup err

helm repo add ${IMAGE_REGISTRY} ${HELM_REPO_URL}
helm repo update
helm pull ${IMAGE_REGISTRY}/${HELM_PULL_NAME} --version ${CHART_VERSION} --untar

cleanup-chart

mv ${HELM_PULL_NAME} ${REPO}/${HELM_DIRECTORY}

copy-crds

cleanup


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

set -x
set -o errexit
set -o nounset
set -o pipefail

SED=sed
if [ "$(uname -s)" = "Darwin" ]; then
    SED=gsed
fi

IMAGE_REGISTRY="${1?First argument is image registry}"
HELM_DESTINATION_REPOSITORY="${2?Second argument is helm repository}"
HELM_TAG="${3?Third argument is helm tag}"
GIT_TAG="${4?Fourth arguement is the Git Tag}"
OUTPUT_DIR="${5?Fifth arguement is output directory}"
LATEST_TAG="${6?Sixth arguement is latest tag}"
SEMVER_GIT_TAG="${GIT_TAG#[^0-9:main]}"

SEMVER="${HELM_TAG#[^0-9]}" # remove any leading non-digits
SEMVER_REGEX='^([0-9]+\.){0,2}(\*|[0-9]+)$'
if [[ ! $SEMVER_GIT_TAG =~ $SEMVER_REGEX ]]; then
  # if not a valid semver, fallback to helm tag semver
  SEMVER_GIT_TAG=$SEMVER
fi

HELM_DESTINATION_OWNER=$(dirname ${HELM_DESTINATION_REPOSITORY})
CHART_NAME=$(basename ${HELM_DESTINATION_REPOSITORY})
CHART_FILE="${OUTPUT_DIR}/helm/${CHART_NAME}-${SEMVER}.tgz"

DOCKER_CONFIG=${DOCKER_CONFIG:-~/.docker}
export HELM_REGISTRY_CONFIG="${DOCKER_CONFIG}/config.json"
export HELM_EXPERIMENTAL_OCI=1
TMPFILE=$(mktemp /tmp/helm-output.XXXXXX)
function cleanup() {
  if [[ "${IMAGE_REGISTRY}" == *"public.ecr.aws"* ]]; then
    echo "If authentication failed: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws"
  else
    echo "If authentication failed: aws ecr get-login-password --region \${AWS_REGION} | docker login --username AWS --password-stdin ${IMAGE_REGISTRY}"
  fi
  rm -f "${TMPFILE}"
}

trap cleanup err
trap "rm -f $TMPFILE" exit
helm push ${CHART_FILE} oci://${IMAGE_REGISTRY}/${HELM_DESTINATION_OWNER} | tee ${TMPFILE}

# Adds a 2nd tag to the helm chart for the bundle-release jobs.
if [[ "${IMAGE_REGISTRY}" != *"public.ecr.aws"* ]]; then
  MANIFEST=$(aws ecr batch-get-image --repository-name "$HELM_DESTINATION_REPOSITORY" --image-ids imageTag=${SEMVER} --query "images[].imageManifest" --output text)
  export AWS_PAGER=""
  aws ecr put-image --repository-name ${HELM_DESTINATION_REPOSITORY} --image-tag ${SEMVER_GIT_TAG}-${LATEST_TAG}-helm --image-manifest "$MANIFEST" --image-manifest-media-type "application/vnd.oci.image.manifest.v1+json"
fi

DIGEST=$(grep Digest $TMPFILE | $SED -e 's/Digest: //')
{
    set +x
    echo
    echo
    echo "helm install ${CHART_NAME} oci://${IMAGE_REGISTRY}/${HELM_DESTINATION_REPOSITORY} --version ${SEMVER} --set sourceRegistry=${IMAGE_REGISTRY}"
}


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

set -x
set -o errexit
set -o nounset
set -o pipefail

SED=sed
if [ "$(uname -s)" = "Darwin" ]; then
    SED=gsed
fi

HELM_DESTINATION_REPOSITORY="${1?First argument is helm destination repository}"
OUTPUT_DIR="${2?Second arguement is output directory}"

CHART_NAME=$(basename ${HELM_DESTINATION_REPOSITORY})
DEST_DIR=${OUTPUT_DIR}/helm/${CHART_NAME}

#
# Search and replace
#
TEMPLATE_DIR=helm/templates
SEDFILE=${OUTPUT_DIR}/helm/sedfile
for file in Chart.yaml values.yaml
do
  $SED -f ${SEDFILE} -i ${DEST_DIR}/${file}
done

if [ -d ${OUTPUT_DIR}/helm/${CHART_NAME}/crds ]; then
  for file in crds/*.yaml
  do
    $SED -f ${SEDFILE} -i ${DEST_DIR}/${file}
  done
fi


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

set -x
set -e
set -o errexit
set -o nounset
set -o pipefail

IMAGE_REGISTRY="${1?First argument is registry}"
HELM_DESTINATION_REPOSITORY="${2?Second argument is helm destination repository}"
OUTPUT_DIR="${3?Third argument is output directory}"
IMAGE_TAG="${4?Fourth argument is image tag}"
HELM_TAG="${5?Fifth argument is helm tag}"
PROJECT_ROOT="${6?Sixth argument is project root}"
LATEST="${7?Seventh argument is latest tag}"
HELM_USE_UPSTREAM_IMAGE="${8?Eigth argument is bool determining whether to use cached upstream images}"
HELM_IMAGE_LIST="${@:9}"

CHART_NAME=$(basename ${HELM_DESTINATION_REPOSITORY})
DEST_DIR=${OUTPUT_DIR}/helm/${CHART_NAME}
SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
PACKAGE_DEPENDENCIES=${PACKAGE_DEPENDENCIES:=""}
FORCE_JSON_SCHEMA_FILE=${FORCE_JSON_SCHEMA_FILE:=""}

#
# Image tags
#
REQUIRES_FILE=${DEST_DIR}/requires.yaml
cat >${REQUIRES_FILE} <<!
---
kind: EksaPackageRequires
metadata:
  name: ${HELM_DESTINATION_REPOSITORY}-${HELM_TAG/v}
  namespace: eksa-packages
spec:
  images:
!
JSON_SCHEMA_FILE=$PROJECT_ROOT/helm/schema.json
SEDFILE=${OUTPUT_DIR}/helm/sedfile
export IMAGE_TAG
export HELM_TAG
export HELM_REGISTRY=$(aws ecr-public describe-registries --region us-east-1  --output text --query 'registries[*].registryUri')
envsubst <$PROJECT_ROOT/helm/sedfile.template >${SEDFILE}
# Semver requires that our version begin with a digit, so strip the v.
echo "s,version: v,version: ,g" >>${SEDFILE}
for IMAGE in ${HELM_IMAGE_LIST:-}
do
  if [ "${IMAGE}" == "${HELM_DESTINATION_REPOSITORY}" ] || [ "${IMAGE_TAG}" != "${HELM_TAG}" ]
  then
    TAG="${IMAGE_TAG}"
  else
    TAG="${LATEST}"
  fi
  IMAGE_SHASUM=$(${SCRIPT_ROOT}/image_shasum.sh ${HELM_REGISTRY} ${IMAGE} ${TAG}) ||
  IMAGE_SHASUM=$(${SCRIPT_ROOT}/image_shasum.sh ${IMAGE_REGISTRY} ${IMAGE} ${TAG})
  echo "s,{{${IMAGE}}},${IMAGE_SHASUM},g" >>${SEDFILE}
  if [ "${TAG}" == "latest" ]
  then
    USE_TAG=$(aws --region us-east-1 ecr-public describe-images --repository-name ${IMAGE} --image-ids imageTag=latest --query 'imageDetails[0].imageTags' --output yaml | grep -v latest | head -1| sed -e 's/- //') ||
    USE_TAG=$(aws ecr describe-images --repository-name ${IMAGE} --image-id imageTag=latest --query 'imageDetails[0].imageTags' --output yaml | grep -v latest | head -1| sed -e 's/- //') ||
    USE_TAG="latest"
  else
    USE_TAG=$TAG
  fi
  # If HELM_USE_UPSTREAM_IMAGE is true, we are using images from upstream.
  # Though we pull images directly from upstream for build tooling checks (i.e.
  # get images shasums), we will use cached images in the helm charts. Cached
  # images follow the convention of ${PROJECT_NAME}/${UPSTREAM_IMAGE_NAME}.
  if [ "${HELM_USE_UPSTREAM_IMAGE}" == true ]
  then
    PROJECT_NAME=$(echo "$HELM_DESTINATION_REPOSITORY" | awk -F "/" '{print $1}')
    IMAGE_REPO="${PROJECT_NAME}/${IMAGE}"
  else
    IMAGE_REPO="${IMAGE}"
  fi
  cat >>${REQUIRES_FILE} <<!
  - repository: ${IMAGE_REPO}
    tag: ${USE_TAG}
    digest: ${IMAGE_SHASUM}
!
done

if [ -n "${FORCE_JSON_SCHEMA_FILE}" ]
then
  JSON_SCHEMA_FILE=${FORCE_JSON_SCHEMA_FILE}
fi

if [ -f ${JSON_SCHEMA_FILE} ]
then
  JSON_SCHEMA=$(cat ${JSON_SCHEMA_FILE} | gzip | base64 | tr -d '\n')
  cat >>${REQUIRES_FILE} <<!
  schema: ${JSON_SCHEMA}
!
fi

if [ -n "${PACKAGE_DEPENDENCIES}" ]; then
  echo "  dependencies:" >> ${REQUIRES_FILE}
  echo ${PACKAGE_DEPENDENCIES} | tr ',' '\n'  | while read dep; do
      echo "  - ${dep}"
  done >> ${REQUIRES_FILE}
fi


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

set -x
set -o errexit
set -o nounset
set -o pipefail

REGISTRY="${1?First argument is registry}"
REPOSITORY="${2?Second argument is repository}"
IMAGE_TAG="${3?Third argument is image tag}"

if [ "${JOB_TYPE:-}" == "presubmit" ]
then
  echo latest
  exit 0
fi
TMPFILE=$(mktemp)
trap "rm -f $TMPFILE" exit
TARGET=${REGISTRY}/${REPOSITORY}:${IMAGE_TAG}
skopeo inspect -n --raw docker://${TARGET} >${TMPFILE}
skopeo manifest-digest ${TMPFILE}


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

# Taken from https://github.com/aws/eks-distro-build-tooling/blob/main/builder-base/install.sh
# TODO: introduce a shared scripts repo to better share things like this

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

setupgo() {
    local -r version=$1
    go install golang.org/dl/go${version}@latest
    go${version} download
    # Removing the patch number as we only care about the minor version of golang
    local -r majorversion=$(cut -d. -f"1,2" <<< $version)
    mkdir -p ${GOPATH}/go${majorversion}/bin
    ln -sf ${GOPATH}/bin/go${version} ${GOPATH}/go${majorversion}/bin/go
    ln -sf ${HOME}/sdk/go${version}/bin/gofmt ${GOPATH}/go${majorversion}/bin/gofmt
}

setupgo "${GOLANG116_VERSION:-1.16.15}"
setupgo "${GOLANG117_VERSION:-1.17.13}"
setupgo "${GOLANG118_VERSION:-1.18.10}"
setupgo "${GOLANG119_VERSION:-1.19.10}"
setupgo "${GOLANG120_VERSION:-1.20.5}"

build::common::use_go_version "1.16"
GOBIN=${GOPATH}/go1.16/bin go install github.com/jaxesn/go-licenses@4497a2a38565e4e6ad095ea8117c25ecd622d0cc

build::common::use_go_version "1.17"
GOBIN=${GOPATH}/go1.17/bin go install github.com/jaxesn/go-licenses@6800d77c11d0ef8628e7eda908b1d1149383ca48

build::common::use_go_version "1.18"
GOBIN=${GOPATH}/go1.18/bin go install github.com/jaxesn/go-licenses@6800d77c11d0ef8628e7eda908b1d1149383ca48

build::common::use_go_version "1.19"
GOBIN=${GOPATH}/go1.19/bin go install github.com/jaxesn/go-licenses@6800d77c11d0ef8628e7eda908b1d1149383ca48

build::common::use_go_version "1.20"
GOBIN=${GOPATH}/go1.20/bin go install github.com/jaxesn/go-licenses@6800d77c11d0ef8628e7eda908b1d1149383ca48

# 1.18 is the default so symlink it to /go/bin
ln -sf ${GOPATH}/go1.18/bin/go-licenses ${GOPATH}/bin


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

set -e
set -o pipefail
set -x

function registry_ready() {
  for i in {1..24}
  do
    if ! curl http://$IMAGE_REPO/ > /dev/null 2>&1;
    then
      echo "Local registry at ${IMAGE_REPO} is not running. Retrying."
      sleep 5
    else
      exit 0
    fi
  done
  echo "Local registry at ${IMAGE_REPO} is not available"
  exit 1
}

registry_ready


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

#set -x
set -o errexit
set -o nounset
set -o pipefail

RETURN=0
SED=sed
if [ "$(uname -s)" = "Darwin" ]; then
    SED=gsed
fi

for GIT_TAG_FILE in projects/*/*/GIT_TAG
do
    VERSION="$(cat $GIT_TAG_FILE | $SED "s,-,--,g")"
    README="$(dirname $GIT_TAG_FILE)/README.md"
    if [ ! -f $README ]
    then
        echo "Missing file $README"
        continue
    fi
    EXPECTED_VERSION="img.shields.io/badge/version-$VERSION"
    if grep -l "$EXPECTED_VERSION" ${README} >/dev/null
    then
        continue
    fi
    if ! grep "img.shields.io/badge/version" ${README} >/dev/null
    then
        echo "Did not find version $README"
        continue
    fi
    RETURN=-1
    ACTUAL_VERSION=$(grep "img.shields.io/badge/version" ${README} | $SED -e 's,.*img.shields.io/badge/version-,,' -e 's/-blue).*$//')
    echo "Version mismatch $README expected $VERSION actual $ACTUAL_VERSION"
    $SED -i -e "s/$ACTUAL_VERSION/$VERSION/" $README
done


#!/usr/bin/env bash
# Copyright 2020 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.

set -o errexit
set -o nounset
set -o pipefail

PROJECT="$1"
TARGET="$2"
IMAGE_REPO="${3:-}"
RELEASE_BRANCH="${4:-}"
ARTIFACTS_BUCKET="${5:-$ARTIFACTS_BUCKET}"
BASE_DIRECTORY="${6:-}"
GO_MOD_CACHE="${7:-}"
REMOVE="${8:-false}"
PLATFORM="${9:-}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"

source "${SCRIPT_ROOT}/common.sh"

# Since we may actually be running docker in docker here for cgo builds
# we need to have the host path base_dir and go_mod_cache and netrc
DOCKER_RUN_BASE_DIRECTORY="${DOCKER_RUN_BASE_DIRECTORY:-$BASE_DIRECTORY}"
DOCKER_RUN_GO_MOD_CACHE="${DOCKER_RUN_GO_MOD_CACHE:-$GO_MOD_CACHE}"

MAKE_VARS="IMAGE_REPO=$IMAGE_REPO ARTIFACTS_BUCKET=$ARTIFACTS_BUCKET"

function remove_container()
{
	docker rm -vf $CONTAINER_ID
}

SKIP_RUN="false"
NAME=""
if [[ "$REMOVE" == "false" ]]; then
	echo "****************************************************************"
	echo "A docker container with the name eks-a-builder will be launched."
	echo "It will be left running to support running consecutive runs."
	echo "Run 'make stop-docker-builder' when you are done to stop it."
	echo "****************************************************************"

	NAME="--name eks-a-builder"

	if docker ps -f name=eks-a-builder | grep -w eks-a-builder; then
		SKIP_RUN="true"
		CONTAINER_ID="eks-a-builder"
	fi
else
	trap "remove_container" EXIT
fi

IMAGE="public.ecr.aws/eks-distro-build-tooling/builder-base:latest"
PLATFORM_ARG=""

if [[ -n "$PLATFORM" ]]; then
	DIGEST=$(docker buildx imagetools inspect --raw public.ecr.aws/eks-distro-build-tooling/builder-base:latest | jq -r ".manifests[] | select(.platform.architecture == \"${PLATFORM#linux/}\") | .digest")
	IMAGE="public.ecr.aws/eks-distro-build-tooling/builder-base@$DIGEST"
	PLATFORM_ARG="--platform $PLATFORM"
	MAKE_VARS=" BINARY_PLATFORMS=$PLATFORM"
fi

if [[ "$SKIP_RUN" == "false" ]]; then
	build::docker::retry_pull $IMAGE

	NETRC=""
	if [ -f $HOME/.netrc ]; then
		DOCKER_RUN_NETRC="${DOCKER_RUN_NETRC:-$HOME/.netrc}"
		NETRC="--mount type=bind,source=$DOCKER_RUN_NETRC,target=/root/.netrc"
	else
		DOCKER_RUN_NETRC=""
	fi

	mkdir -p $DOCKER_RUN_GO_MOD_CACHE
	CONTAINER_ID=$(build::common::echo_and_run docker run -d $NAME --privileged $NETRC $PLATFORM_ARG \
		--mount type=bind,source=$DOCKER_RUN_BASE_DIRECTORY,target=/eks-anywhere-build-tooling \
		--mount type=bind,source=$DOCKER_RUN_GO_MOD_CACHE,target=/mod-cache \
		-v /var/run/docker.sock:/var/run/docker.sock \
		-e GOPROXY=${GOPROXY:-} -e GOMODCACHE=/mod-cache -e DOCKER_RUN_BASE_DIRECTORY=$DOCKER_RUN_BASE_DIRECTORY -e DOCKER_RUN_GO_MOD_CACHE=$DOCKER_RUN_GO_MOD_CACHE -e DOCKER_RUN_NETRC=$DOCKER_RUN_NETRC \
		--entrypoint sleep $IMAGE infinity)

	docker exec -it $CONTAINER_ID git config --global --add safe.directory /eks-anywhere-build-tooling
fi

build::common::echo_and_run docker exec -e RELEASE_BRANCH=$RELEASE_BRANCH -it $CONTAINER_ID \
	make $TARGET -C /eks-anywhere-build-tooling/projects/$PROJECT $MAKE_VARS


#!/usr/bin/env bash

set -x
set -e
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

source /docker.sh

CODEBUILD_CI="${CODEBUILD_CI:-false}"
GIT_CONFIG_SCOPE="--global"
if [[ "$CODEBUILD_CI" = "true" ]] && [[ "$CODEBUILD_BUILD_ID" =~ "aws-staging-bundle-build" ]]; then
    GIT_CONFIG_SCOPE="--system"
fi

if [ ! -d "/root/.docker" ]; then
    mkdir -p /root/.docker
fi

cp config/docker-ecr-config.json /root/.docker/config.json
git config ${GIT_CONFIG_SCOPE} credential.helper '!aws codecommit credential-helper $@'
git config ${GIT_CONFIG_SCOPE} credential.UseHttpPath true

start::dockerd
wait::for::dockerd

build::docker::retry_pull public.ecr.aws/eks-distro-build-tooling/binfmt-misc:qemu-v7.0.0

docker run --privileged --rm public.ecr.aws/eks-distro-build-tooling/binfmt-misc:qemu-v7.0.0 --install aarch64,amd64


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

set -o errexit
set -o nounset
set -o pipefail

PROJECT_ROOT="$1"
TARGET_FILE="$2"
REPO="$3"
GOLANG_VERSION="$4"
BINARY_PLATFORMS="$5"
SOURCE_PATTERN="$6"
GOBUILD_COMMAND="$7"
EXTRA_GOBUILD_FLAGS="$8"
GO_LDFLAGS="$9"
CGO_ENABLED="${10}"
CGO_LDFLAGS="${11}"
REPO_SUBPATH="${12:-}"
ALL_TARGET_FILES="${13:-}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

function build::simple::print_go_env(){
  for var in "GOOS" "GOARCH" "CGO_ENABLED" "GOCACHE" "GOFLAGS"; do
    if [ -n "${!var:-}" ]; then
      echo "$var: ${!var:-}"
    fi
    if [ "$var" = "CGO_ENABLED" ] && [ "${!var:-}" = "1" ]; then
      for other in "CGO_LDFLAGS" "CGO_CFLAGS" "LD_LIBRARY_PATH" "PKG_CONFIG_PATH"; do echo "$other: ${!other:-}"; done
    fi
  done
}

function build::simple::binaries(){
  mkdir -p $(dirname $TARGET_FILE)
  cd "$PROJECT_ROOT/$REPO/$REPO_SUBPATH"
  build::common::use_go_version $GOLANG_VERSION
  SUPPORTED_PLATFORMS=(${BINARY_PLATFORMS// / })
  for platform in "${SUPPORTED_PLATFORMS[@]}"; do
    OS="$(cut -d '/' -f1 <<< ${platform})"
    ARCH="$(cut -d '/' -f2 <<< ${platform})"
    if [ $CGO_ENABLED = 1 ]; then
      export CGO_LDFLAGS="$CGO_LDFLAGS,-L$PROJECT_ROOT/_output/source/$OS-$ARCH/usr/lib64"
      export CGO_CFLAGS="-I$PROJECT_ROOT/_output/source/$OS-$ARCH/usr/include"
      export LD_LIBRARY_PATH=$PROJECT_ROOT/_output/source/$OS-$ARCH/usr/lib64:${LD_LIBRARY_PATH-}
      export PKG_CONFIG_PATH=$PROJECT_ROOT/_output/source/$OS-$ARCH/usr/lib64/pkgconfig:${PKG_CONFIG_PATH-}
    fi

    # target file is meant to be treated as a folder since multiple binaries will written out
    if [[ "$TARGET_FILE" == */ ]]; then
      mkdir -p $TARGET_FILE
    fi

    echo "Building binary(s): $ALL_TARGET_FILES"
    export CGO_ENABLED=$CGO_ENABLED GOOS=$OS GOARCH=$ARCH

    build::simple::print_go_env

    build::common::echo_and_run go $GOBUILD_COMMAND -trimpath -a -ldflags "$GO_LDFLAGS" $EXTRA_GOBUILD_FLAGS -o $TARGET_FILE $SOURCE_PATTERN

    if [[ "$TARGET_FILE" == */ ]]; then
      # in the case of outputing to a directory, the files will be named by the basename of the source pattern
      # these need to be renamed to match the configured name from ALL_TARGET_FILES
      TARGET_FILES=(${ALL_TARGET_FILES// / })
      index=0
      for source in $SOURCE_PATTERN; do
        if [ "$(basename $source)" != "${TARGET_FILES[$index]}" ] && [ -f $TARGET_FILE$(basename $source) ]; then
          # in the case of multiple target files but the first is a ., we cant move . but it should already be named correctly
          build::common::echo_and_run mv $TARGET_FILE$(basename $source) $TARGET_FILE${TARGET_FILES[$index]}
        fi
        ((index=index+1))
      done
    fi
  done
}

build::simple::binaries


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

set -o errexit
set -o nounset
set -o pipefail

TAR_FILE_PREFIX="$1"
OUTPUT_DIR="$2"
OUTPUT_BIN_DIR="$3"
TAG="$4"
BINARY_PLATFORMS="$5"
TAR_PATH="$6"
GIT_HASH="$7"

LICENSE_PATHS=($(find $OUTPUT_DIR -type d -name "LICENSES"))
ATTRIBUTION_PATHS=($(find $OUTPUT_DIR -type f -name "*ATTRIBUTION.txt"))

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

function build::simple::tarball() {
  build::common::ensure_tar
  mkdir -p "$TAR_PATH"
  SUPPORTED_PLATFORMS=(${BINARY_PLATFORMS// / })
  for platform in "${SUPPORTED_PLATFORMS[@]}"; do
    OS="$(cut -d '/' -f1 <<< ${platform})"
    ARCH="$(cut -d '/' -f2 <<< ${platform})"
    TAR_FILE="${TAR_FILE_PREFIX}-${OS}-${ARCH}-${TAG}.tar.gz"

    for path in "${LICENSE_PATHS[@]}"; do
      build::common::echo_and_run cp -rf $path ${OUTPUT_BIN_DIR}/${OS}-${ARCH}/
    done
    for path in "${ATTRIBUTION_PATHS[@]}"; do
      build::common::echo_and_run cp $path ${OUTPUT_BIN_DIR}/${OS}-${ARCH}/
    done
    build::common::create_tarball ${TAR_PATH}/${TAR_FILE} ${OUTPUT_BIN_DIR}/${OS}-${ARCH} .
  done
  echo $GIT_HASH > $TAR_PATH/githash
}

build::simple::tarball


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

set -o errexit
set -o nounset
set -o pipefail

MAKE_ROOT="$1"
PROJECT_ROOT="$2"
OUTPUT_BIN_DIR="$3"

if [ ! -d ${OUTPUT_BIN_DIR} ] ;  then
    echo "${OUTPUT_BIN_DIR} not present! Run 'make binaries'"
    exit 1
fi

CHECKSUMS_FILE=$PROJECT_ROOT/CHECKSUMS

rm -f $CHECKSUMS_FILE
for file in $(find ${OUTPUT_BIN_DIR} -type f | sort); do
    filepath=$(realpath --relative-base=$MAKE_ROOT $file)
    sha256sum $filepath >> $CHECKSUMS_FILE
done

echo "*************** CHECKSUMS ***************"
cat $CHECKSUMS_FILE
echo "*****************************************"


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

set -x
set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

if [[ -z "${JOB_TYPE:-}" ]] && [[ -z "${CODEBUILD_CI:-}" ]]; then
    exit 0
fi

GOPATH=$GOPATH
if [ -d "/go" ]; then
    GOPATH="/go"
fi

for go in $GOPATH/go*/bin/go; do
    VERSION=$($go version | grep -o "go[0-9].* " | grep -o "[0-9\.]*")
    NOPATCH=$(cut -d. -f"1,2" <<< $VERSION)
    sed -i "s,\${GOLANG${NOPATCH//./}_VERSION:-.*},\${GOLANG${NOPATCH//./}_VERSION:-$VERSION}," ./build/lib/install_go_versions.sh
done


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

set -o errexit
set -o nounset
set -o pipefail

SRC_TAR_PATH="${1?Specify first argument - source tar path}"
ARTIFACTS_BUCKET="${2?Specify second argument - artifacts buckets}"
PROJECT_PATH="${3? Specify third argument - project path}"
BUILD_IDENTIFIER="${4? Specify fourth argument - build identifier}"
GIT_HASH="${5?Specify fifth argument - git hash of the tar builds}"
LATEST_TAG="${6?Specify sixth argument - folder name corresponding to latest build}"
UPLOAD_DRY_RUN="${7?Specify seventh argument - Dry run upload}"
UPLOAD_DO_NOT_DELETE="${8?Specify eighth argument - Do not delete extra files in s3 bucket on upload}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

build::common::upload_artifacts $SRC_TAR_PATH $ARTIFACTS_BUCKET $PROJECT_PATH $BUILD_IDENTIFIER $GIT_HASH $LATEST_TAG $UPLOAD_DRY_RUN $UPLOAD_DO_NOT_DELETE


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

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

PROJECT_ROOT="$1"
ARTIFACTS_FOLDER="$2"
GIT_TAG="$3"
FAKE_ARM_ARTIFACTS_FOR_VALIDATION="$4"
FAKE_AMD_BINARIES_FOR_VALIDATION="$5"
IMAGE_FORMAT="${6:-}"
IMAGE_OS="${7:-}"

EXPECTED_FILES_PATH=$PROJECT_ROOT/expected_artifacts
if [ -n "$IMAGE_FORMAT" ]; then
  if [ "$IMAGE_OS" = "bottlerocket" ]; then
    EXPECTED_FILES_PATH=${PROJECT_ROOT}/expected-artifacts/expected_artifacts_${IMAGE_FORMAT}_bottlerocket
  else
    EXPECTED_FILES_PATH=${PROJECT_ROOT}/expected-artifacts/expected_artifacts_${IMAGE_FORMAT}
  fi
fi

REALPATH=realpath
if which grealpath &>/dev/null; then
    REALPATH=grealpath
fi

ACTUAL_FILES=$(mktemp)
find "$ARTIFACTS_FOLDER" \
     -type f \
     -exec $REALPATH --relative-base="$ARTIFACTS_FOLDER" {} \; \
     > "$ACTUAL_FILES"

EXPECTED_FILES=$(mktemp)
build::common::echo_and_run export GIT_TAG=$GIT_TAG
build::common::echo_and_run export IMAGE_OS=$IMAGE_OS
envsubst "\$GIT_TAG:\$IMAGE_OS" \
         < "$EXPECTED_FILES_PATH" \
         > "$EXPECTED_FILES"

if $FAKE_ARM_ARTIFACTS_FOR_VALIDATION; then
    echo "Faking arm64 artifacts"
    sed -i '/arm64/d' "$EXPECTED_FILES"
fi

if $FAKE_AMD_BINARIES_FOR_VALIDATION; then
    echo "Faking amd64 artifacts"
    sed -i '/amd64/d' "$EXPECTED_FILES"
fi

# The versions of sort found on macOS and Linux can behave
# differently. That's why we sort each file here and now, to ensure
# that whatever version is in use, it's consistent.
echo "diffing $EXPECTED_FILES $ACTUAL_FILES"
if ! diff -q <(sort "$EXPECTED_FILES") <(sort "$ACTUAL_FILES"); then
    echo "Artifacts directory does not matched expected!"
    diff -y <(sort "$EXPECTED_FILES") <(sort "$ACTUAL_FILES")
    exit 1
fi


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

set -o errexit
set -o nounset
set -o pipefail

MAKE_ROOT="$1"
PROJECT_ROOT="$2"
OUTPUT_BIN_DIR="$3"
FAKE_ARM_ARTIFACTS_FOR_VALIDATION="$4"
FAKE_AMD_BINARIES_FOR_VALIDATION="$5"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"

cd $MAKE_ROOT

CHECKSUMS_FILE=$PROJECT_ROOT/CHECKSUMS

if $FAKE_ARM_ARTIFACTS_FOR_VALIDATION; then
	TEMP_FILE=$(mktemp)
	grep -v 'arm64' $CHECKSUMS_FILE > $TEMP_FILE
	CHECKSUMS_FILE=$TEMP_FILE
fi

if $FAKE_AMD_BINARIES_FOR_VALIDATION; then
	TEMP_FILE=$(mktemp)
	grep -v 'amd64' $CHECKSUMS_FILE > $TEMP_FILE
	CHECKSUMS_FILE=$TEMP_FILE
fi

if ! sha256sum -c $CHECKSUMS_FILE; then
	echo "Checksums do not match!"
	echo "The correct checksums are printed below"
	echo "Please only update if changing GIT_TAG or build flags."
	$SCRIPT_ROOT/update_checksums.sh $MAKE_ROOT $PROJECT_ROOT $OUTPUT_BIN_DIR
	exit 1
fi


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

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"

source "${SCRIPT_ROOT}/eksd_releases.sh"

FAILED=0
for release_branch in $(cat $SCRIPT_ROOT/../../release/SUPPORTED_RELEASE_BRANCHES); do
    YAML_URL=$(build::eksd_releases::get_release_yaml_url $release_branch)
    HTTP_CODE=$(curl -I -L -s -o /dev/null -w "%{http_code}" $YAML_URL)
    if [[ "$HTTP_CODE" != "200" ]]; then
        echo "EKS-D manifest does not exist: $YAML_URL"
        FAILED=1
        continue
    fi

    build::eksd_releases::load_release_yaml $release_branch > /dev/null
    COMPONENT_VERSION=$(build::eksd_releases::get_eksd_component_version "kubernetes" $release_branch)
    COMPONENT_VERSION_FROM_YAML=$(yq e ".releases[] | select(.branch==\"${release_branch}\").kubeVersion" $SCRIPT_ROOT/../../EKSD_LATEST_RELEASES)

    if [[ "$COMPONENT_VERSION" != "$COMPONENT_VERSION_FROM_YAML" ]]; then
        echo "kubeVersion: $COMPONENT_VERSION_FROM_YAML does not match version from EKS-D release manifest: $COMPONENT_VERSION"
        FAILED=1
    fi
done

if [[ "$FAILED" == "0" ]]; then
    echo "All EKS-D versions validated!"
fi
exit $FAILED


#!/usr/bin/env bash

# Copyright 2014 The Kubernetes Authors.
# - https://github.com/kubernetes/kubernetes/blob/master/hack/lib/version.sh
# Copyright 2020 The Kubernetes Authors.
# - https://github.com/kubernetes-sigs/cluster-api/blob/main/hack/version.sh
# Modifications Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. Licensed under the Apache2 License

# Modifications:
# Adapted upsteam code from kubernetes/kubernetes and CAPI to support the CAPI use case, but also be generic for other
# projects built in this repo

set -o errexit
set -o nounset
set -o pipefail

version::get_version_vars() {
    local -r repo=$1
    GIT_RELEASE_TAG=$(git -C $repo describe --match 'v[0-9]*.[0-9]*.[0-9]**' --abbrev=0 --tags)
    GIT_RELEASE_COMMIT=$(git -C $repo rev-list -n 1  "${GIT_RELEASE_TAG}")

    GIT_COMMIT=$GIT_RELEASE_COMMIT

    # from k8s.io/hack/lib/version.sh
    # Use git describe to find the version based on tags.
    if GIT_VERSION=$GIT_RELEASE_TAG; then
        # Try to match the "git describe" output to a regex to try to extract
        # the "major" and "minor" versions and whether this is the exact tagged
        # version or whether the tree is between two tagged versions.
        if [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then
            GIT_MAJOR=${BASH_REMATCH[1]}
            GIT_MINOR=${BASH_REMATCH[2]}
        fi

        # If GIT_VERSION is not a valid Semantic Version, then refuse to build.
        if ! [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
            echo "GIT_VERSION should be a valid Semantic Version. Current value: ${GIT_VERSION}"
            echo "Please see more details here: https://semver.org"
            exit 1
        fi
    fi

}

# Prints the value that needs to be passed to the -ldflags parameter of go build
version::ldflags() {
    local -r repo=$1
    local -r package_prefix=$2
    version::get_version_vars $repo

    # from k8s.io/hack/lib/version.sh
    local -a ldflags
    function add_ldflag() {
        local key=${1}
        local val=${2}
        ldflags+=(
            "-X '${package_prefix}.${key}=${val}'"
        )
    }
    DATE=date
    if which gdate &>/dev/null; then
        DATE=gdate
    elif which gnudate &>/dev/null; then
        DATE=gnudate
    fi

    # buildDate is not actual buildDate to avoid it breaking reproducible checksums
    # instead it is the date of the last commit, either the upstream TAG commit or the latest patch applied
    SOURCE_DATE_EPOCH=$(git -C $repo log -1 --format=%at)
    add_ldflag "buildDate" "$(${DATE} --date=@${SOURCE_DATE_EPOCH} -u +'%Y-%m-%dT%H:%M:%SZ')"
    add_ldflag "gitCommit" "${GIT_COMMIT}"
    add_ldflag "gitTreeState" "clean"
    add_ldflag "gitMajor" "${GIT_MAJOR}"
    add_ldflag "gitMinor" "${GIT_MINOR}"
    add_ldflag "gitVersion" "${GIT_VERSION}"
    add_ldflag "gitReleaseCommit" "${GIT_RELEASE_COMMIT}"

    # The -ldflags parameter takes a single string, so join the output.
    echo "${ldflags[*]-}"
}

version::ldflags $1 $2


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

set -o errexit
set -o nounset
set -o pipefail

TAG="$1"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
source "${SCRIPT_ROOT}/common.sh"

build::common::wait_for_tag $TAG


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

set -e
set -o pipefail

if [[ -z "${JOB_TYPE:-}" ]] && [[ -z "${CODEBUILD_CI:-}" ]]; then
    exit 0
fi

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"

source $SCRIPT_ROOT/../lib/common.sh

SKIP_PR="${1:-false}"

ORIGIN_ORG="eks-distro-pr-bot"
UPSTREAM_ORG="aws"
REPO="eks-anywhere-build-tooling"

MAIN_BRANCH="main"

if [[ -n "${CODEBUILD_SOURCE_VERSION:-}" ]]; then
    MAIN_BRANCH="$CODEBUILD_SOURCE_VERSION"
fi

if [[ -n "${PULL_BASE_REF:-}" ]]; then
    MAIN_BRANCH="$PULL_BASE_REF"
fi

function pr::github::should_auth()
{
    [[ "${JOB_TYPE:-}" == "periodic" ]] || [[ -n "${CODEBUILD_CI:-}" ]]
}

function commit_push()
{
    local -r pr_branch="$1"
    local force_push="$2"

    if [[ "$force_push" = "true" ]]; then
        force_push="-f"
    else
        force_push=""
    fi

    if build::common::echo_and_run git push $force_push -u bot $pr_branch; then
        echo "Commit pushed"
        return
    fi

    # Other jobs could be running and updating the same branch, which is expected
    # attempt to rebase and retry
    build::common::echo_and_run git fetch -q bot
    build::common::echo_and_run git branch --set-upstream-to=bot/$pr_branch $pr_branch

    # rebase succeeded, return 1 to retry the push
    if build::common::echo_and_run git rebase bot/$pr_branch; then
        echo "Rebased local branch, retrying"
        return 1
    fi

    git status
    git diff HEAD -- $(git diff --name-only --diff-filter=U)

    # rebase failed with conflict, exit with error
    exit 1
}

function pr::commit::push()
{
    local -r commit_message="$1"
    local -r pr_branch="$2"
    local -r force_push="${3:-true}"

    build::common::echo_and_run git checkout -B $pr_branch

    git diff --staged
    local -r files_added=$(git diff --staged --name-only)
    if [ "$files_added" = "" ]; then
        echo "No files changed to commit"
        return 1
    fi

    build::common::echo_and_run git status
    build::common::echo_and_run git commit -m "$commit_message" || true

    if ! pr::github::should_auth; then
        echo "Skipping commit push due to missing correct job type"
        return 1
    fi

    if pr::github::auth; then
        retry commit_push "$pr_branch" "$force_push"
    fi
}

function pr::create()
{
    local -r pr_title="$1"
    local -r pr_branch="$2"
    local -r pr_body="$3"

    if ! pr::github::should_auth; then
        echo "Skipping PR creation due to missing correct job type"
        return
    fi

    if [[ "${SKIP_PR}" == "true" ]]; then
        echo "Skipping PR creation"
        return
    fi

    if ! pr::github::auth; then
        echo "Skipping PR creation due to missing Github auth creds"
        return
    fi

    if ! git ls-remote --exit-code bot $pr_branch; then
        echo "Skipping PR creation due to missing upstream branch: $pr_branch"
        return
    fi

    local pr_exists=$(GH_PAGER='' gh pr list --json number -H "$pr_branch")
    if [ "$pr_exists" != "[]" ]; then
        # already exists
        echo "PR already exists."
        return
    fi

    build::common::echo_and_run gh pr create --title "$pr_title" --body "$pr_body" --base $MAIN_BRANCH --head $ORIGIN_ORG:$pr_branch
}

function pr::github::auth()
{
    if [[ -z "${GITHUB_TOKEN:-}" ]] && [[ ! -f /secrets/github-secrets/token ]]; then
        echo "Missing GITHUB_TOKEN or /secrets/github-secrets/token, cannot authenticate"
        return 1
    fi

    if [ -f /secrets/github-secrets/token ]; then
        gh auth login --with-token < /secrets/github-secrets/token
    fi

    gh auth setup-git
    gh api rate_limit

    gh repo set-default "${UPSTREAM_ORG}/${REPO}"
}

function pr::create::pr_body(){
    pr_body=""
    case $1 in
    attribution)
        pr_body=$(cat <<'EOF'
This PR updates the ATTRIBUTION.txt files across all dependency projects if there have been changes.

These files should only be changing due to project GIT_TAG bumps or Golang version upgrades. If changes are for any other reason, please review carefully before merging!
EOF
)
        ;;
    checksums)
        pr_body=$(cat <<EOF
This PR updates the CHECKSUMS files across all dependency projects if there have been changes.

These files should only be changing due to project GIT_TAG bumps or Golang version upgrades. If changes are for any other reason, please review carefully before merging!

These files were generated using $CODEBUILD_BUILD_IMAGE
EOF
)
        ;;
    makehelp)
        pr_body=$(cat <<'EOF'
This PR updates the Help.mk files across all dependency projects if there have been changes.
EOF
)
        ;;
    go-mod)
        pr_body=$(cat <<'EOF'
This PR updates the checked in go.mod and go.sum files across all dependency projects to support automated vulnerability scanning.
EOF
)
        ;;
    *)
        echo "Invalid argument: $1"
        exit 1
        ;;
    esac
    PROW_BUCKET_NAME=$(echo $JOB_SPEC | jq -r ".decoration_config.gcs_configuration.bucket" | awk -F// '{print $NF}')
    full_pr_body=$(printf "%s\n\n/hold\n\nBy submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice." "$pr_body")

    printf "$full_pr_body"
}

function pr::create::attribution() {
    local -r pr_title="Update ATTRIBUTION.txt files"
    local commit_message="[PR BOT] Update ATTRIBUTION.txt files"
    local pr_branch="attribution-files-update-$MAIN_BRANCH"
    local -r pr_body=$(pr::create::pr_body "attribution")

    local force_push="true"
    if [ -n "${CODEBUILD_RESOLVED_SOURCE_VERSION:-}" ]; then
        pr_branch+="-$CODEBUILD_RESOLVED_SOURCE_VERSION"
        force_push="false"

        local -r changed_files=$(git diff --staged --name-only | grep "^projects" | cut -d '/' -f2- | uniq | tr  '\n' ' ')
        commit_message="[PR BOT] Update $changed_files"
    fi

    # always try to create pr if running in codebuild
    if pr::commit::push "$commit_message" "$pr_branch" "$force_push" || [ -n "${CODEBUILD_RESOLVED_SOURCE_VERSION:-}" ]; then
        pr::create "$pr_title" "$pr_branch" "$pr_body"
    fi
}

function pr::create::checksums() {
    local -r pr_title="Update CHECKSUMS files"
    local pr_branch="checksums-files-update-$MAIN_BRANCH"
    local -r pr_body=$(pr::create::pr_body "checksums")

    local force_push="true"
    if [ -n "${CODEBUILD_RESOLVED_SOURCE_VERSION:-}" ]; then
        pr_branch+="-$CODEBUILD_RESOLVED_SOURCE_VERSION"
        force_push="false"
    fi

    # This file is being added as it may have been updated by the last lines of ./build/lib/update_go_versions.sh,
    # which replaces the go version in this script with the go version(s) in the builder base if they are newer
    # when running `make update-checksum-files`
    build::common::echo_and_run git add ./build/lib/install_go_versions.sh

    # stash checksums and attribution and help.mk files
    build::common::echo_and_run git stash --keep-index

    # ignore return since we always want to try and create_pr
    pr::commit::push "[PR BOT] Update install_go_versions.sh" "$pr_branch" "$force_push" || true

    pr::stash::pop

    # Add checksum files
    for FILE in $(find . -type f -name CHECKSUMS); do
        if [[ "0 1" == "$(git diff --numstat $FILE | awk -F ' ' '{print $1,$2}')" ]]; then
            echo "Ignoring changes to $FILE since only changes are deletions"
            git diff $FILE
            git checkout -- $FILE
            continue
        fi
        pr::file:add $FILE
    done

    # stash attribution and help.mk files
    build::common::echo_and_run git stash --keep-index

    local -r changed_files=$(git diff --staged --name-only | grep "^projects" | cut -d '/' -f2- | uniq | tr  '\n' ' ')
    local -r commit_message="[PR BOT] Update $changed_files"

    # always try to create pr if running in codebuild
    if pr::commit::push "$commit_message" "$pr_branch" "$force_push" || [ -n "${CODEBUILD_RESOLVED_SOURCE_VERSION:-}" ]; then
        pr::create "$pr_title" "$pr_branch" "$pr_body"
    fi
}

function pr::create::help() {
    local -r pr_title="Update Makefile generated help"
    local -r commit_message="[PR BOT] Update Help.mk files"
    local -r pr_branch="help-makefiles-update-$MAIN_BRANCH"
    local -r pr_body=$(pr::create::pr_body "makehelp")

    if pr::commit::push "$commit_message" "$pr_branch"; then
        pr::create "$pr_title" "$pr_branch" "$pr_body"
    fi
}

function pr::create::go-mod() {
    local -r pr_title="Update go.mod files"
    local -r commit_message="[PR BOT] Update go.mod files"
    local -r pr_branch="go-mod-update-$MAIN_BRANCH"
    local -r pr_body=$(pr::create::pr_body "go-mod")

    if pr::commit::push "$commit_message" "$pr_branch"; then
        pr::create "$pr_title" "$pr_branch" "$pr_body"
    fi
}

function pr::file:add() {
    local -r file="$1"

    if git check-ignore -q $FILE; then
        return
    fi

    local -r diff="$(git diff --ignore-blank-lines --ignore-all-space $FILE)"
    if [[ -z $diff ]]; then
        return
    fi

    git add $file
}

function pr::stash::pop() {
    if [ "$(git stash list)" != "" ]; then
        build::common::echo_and_run git stash pop
    fi
}

cd ${SCRIPT_ROOT}/../../
git config --global push.default current
git config user.name "EKS Distro PR Bot"
git config user.email "aws-model-rocket-bots+eksdistroprbot@amazon.com"
git config remote.upstream.url >&- || git remote add upstream https://github.com/${UPSTREAM_ORG}/${REPO}.git
git config remote.bot.url >&- || git remote add bot https://github.com/${ORIGIN_ORG}/${REPO}.git

# Files have already changed, stash to perform rebase
build::common::echo_and_run git stash

build::common::echo_and_run git checkout $MAIN_BRANCH

# avoid hitting github limits in presubmits
if pr::github::should_auth; then
    build::common::echo_and_run retry git fetch -q upstream

    # there will be conflicts before we are on the bots fork at this point
    # -Xtheirs instructs git to favor the changes from the current branch
    build::common::echo_and_run git rebase -Xtheirs upstream/$MAIN_BRANCH
fi

pr::stash::pop

echo -e "\n-------------------------- Adding Checksum files ---------------------------\n"

pr::create::checksums

echo -e "\n----------------------------------------------------------------------------\n"

build::common::echo_and_run git checkout $MAIN_BRANCH

pr::stash::pop

echo -e "\n-------------------------- Adding ATTRIBUTION files ------------------------\n"

# Add attribution files
for FILE in $(find . -type f \( -name "*ATTRIBUTION.txt" ! -path "*/_output/*" \)); do
    pr::file:add $FILE
done

# stash help.mk files
git stash --keep-index

pr::create::attribution

echo -e "\n----------------------------------------------------------------------------\n"

build::common::echo_and_run git checkout $MAIN_BRANCH

pr::stash::pop

echo -e "\n-------------------------- Adding Help.mk files -----------------------------\n"

# Add help.mk/Makefile files
for FILE in $(find . -type f \( -name Help.mk -o -name Makefile \)); do
    pr::file:add $FILE
done

pr::create::help

echo -e "\n----------------------------------------------------------------------------\n"


#!/usr/bin/env bash
# Copyright 2020 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.

set -e
set -o errexit
set -o nounset
set -o pipefail
shopt -s globstar

PROJECT="$1"
TARGET="$2"

MAKE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"
PROJECT_ROOT=$MAKE_ROOT/$PROJECT

OUTPUT_DIR=$MAKE_ROOT/_output
mkdir -p $OUTPUT_DIR
touch $OUTPUT_DIR/total_summary.txt

function build::attribution::generate(){
    make -C $PROJECT_ROOT $TARGET

    if ls $PROJECT_ROOT/_output/**/summary.txt 1> /dev/null 2>&1; then
        for summary in $PROJECT_ROOT/_output/**/summary.txt; do
            sed -i "s/+.*=/ =/g" $summary
            awk -F" => " '{ count[$1]+=$2} END { for (item in count) printf("%s => %d\n", item, count[item]) }' \
                $summary $OUTPUT_DIR/total_summary.txt | sort > $OUTPUT_DIR/total_summary.tmp && mv $OUTPUT_DIR/total_summary.tmp $OUTPUT_DIR/total_summary.txt
        done
    fi
}

# Some projects have specific folders for different kubernetes release
# dynamically find all versions to avoid having to update with every release
RELEASE_FOLDER=$(find $PROJECT_ROOT -type d -maxdepth 1 -name "1-*")
SUPPORTED_RELEASE_BRANCHES=$(cat $MAKE_ROOT/release/SUPPORTED_RELEASE_BRANCHES)

if [ -z "${RELEASE_FOLDER}" ]; then
    build::attribution::generate
else
    LAST_GIT_TAG=""
    LAST_RELEASE_BRANCH=""
    for release_folder in $PROJECT_ROOT/1-*/ ; do
        release=$(basename $release_folder)

        # if release is no longer a supported release branch, skip it
        if [[ ! "$SUPPORTED_RELEASE_BRANCHES" == *"$release"* ]]; then
            echo "Skipping $release, no longer supported"
            continue
        fi

        # some projects have release folders but no git_tag since they do not build binaries
        if [ ! -f $PROJECT_ROOT/$release/GIT_TAG ]; then
            continue
        fi

        export RELEASE_BRANCH="$release"

        GIT_TAG="$(cat $PROJECT_ROOT/$release/GIT_TAG)"
        if [ "$GIT_TAG" != "$LAST_GIT_TAG" ] || [ $TARGET == "update-go-mods" ]; then
            # clean before regenerating to ensure there are no intermediate files left around
            make -C $PROJECT_ROOT clean clean-go-cache
            build::attribution::generate $release
        else
            # if the git_tags match across release branches, save the output state to avoid
            # rebuilding/regenerating
            if [[ $TARGET == *"checksums"* ]]; then
                echo "Copying $LAST_RELEASE_BRANCH CHECKSUMS to $release"
                mkdir -p $PROJECT_ROOT/_output/$release
                sed "s/$LAST_RELEASE_BRANCH/$release/" $PROJECT_ROOT/$LAST_RELEASE_BRANCH/CHECKSUMS > $PROJECT_ROOT/$release/CHECKSUMS
            fi

            if [[ $TARGET == *"attribution"* ]]; then
                echo "Copying $LAST_RELEASE_BRANCH ATTRIBUTION to $release"
                mkdir -p $PROJECT_ROOT/_output/$release
                cp -rf $PROJECT_ROOT/$LAST_RELEASE_BRANCH/*TTRIBUTION.txt $PROJECT_ROOT/$release
            fi
        fi
        LAST_GIT_TAG="$GIT_TAG"
        LAST_RELEASE_BRANCH="$release"
    done
fi

make -C $PROJECT_ROOT clean clean-go-cache


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

set -x
set -o errexit
set -o pipefail

REPO="$1"
OUTPUT_DIR="$2"
ARTIFACTS_PATH="$3"
TAG="$4"
IMAGE_REPO="$5"
IMAGE_TAG="$6"

MAKE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
source "${MAKE_ROOT}/../../../build/lib/common.sh"

mkdir -p $ARTIFACTS_PATH

# TODO: once cloning snow provider source run standard make targert
mkdir -p $ARTIFACTS_PATH/manifests/infrastructure-snow/$TAG
cp -rf manifests/* $ARTIFACTS_PATH/manifests/infrastructure-snow/$TAG


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

set -o errexit
set -o nounset
set -o pipefail

AMI_MANIFEST_OUTPUT="${1?Specify first argument - AMI manifest output file from packer}"
IMAGE_FORMAT="${2?Specify second argument - Format for exported image \(vmdk\|raw\|vhd\)}"
S3_DST_EXPORT_PATH="${3?Specify third argument - Destination S3 path}"
REPLICAS="${4?Specify fourth argument - Comma separated list of s3 destinations for exported image copies}"

ARTIFACT_ID=$(cat $AMI_MANIFEST_OUTPUT | jq -r '.builds[0].artifact_id')
ARTIFACT_ID_SPLIT=(${ARTIFACT_ID//:/ })
AMI_ID=${ARTIFACT_ID_SPLIT[1]}

REPLICAS_SPLIT=(${REPLICAS//,/ })

DST_BUCKET_PATH=${S3_DST_EXPORT_PATH#"s3://"}
DST_BUCKET_NAME=${DST_BUCKET_PATH%%/*}
DST_PATH=${DST_BUCKET_PATH#"$DST_BUCKET_NAME/"}

EXPORTED_IMAGE_PREFIX="$DST_PATH"

EXPORT_RESPONSE=$(aws ec2 export-image --disk-image-format $IMAGE_FORMAT --s3-export-location S3Bucket=$DST_BUCKET_NAME,S3Prefix=$EXPORTED_IMAGE_PREFIX --image-id $AMI_ID)
echo $EXPORT_RESPONSE

EXPORT_TASK_ID=$(echo $EXPORT_RESPONSE | jq -r '.ExportImageTaskId')
EXPORTED_IMAGE_KEY="${EXPORTED_IMAGE_PREFIX}${EXPORT_TASK_ID}.${IMAGE_FORMAT}"
EXPORTED_IMAGE_LOCATION="s3://${DST_BUCKET_NAME}/${EXPORTED_IMAGE_KEY}"
EXPORTED_IMAGE_URL="https://${DST_BUCKET_NAME}.s3.amazonaws.com/${EXPORTED_IMAGE_KEY}"

FINAL_STATUSES=(completed deleted)
STATUS=$(echo $EXPORT_RESPONSE | jq -r '.Status')
STATUS_MESSAGE=$(echo $EXPORT_RESPONSE | jq -r '.StatusMessage')
PROGRESS=$(echo $EXPORT_RESPONSE | jq -r '.Progress')

until [[ "${FINAL_STATUSES[*]}" =~ "${STATUS}" ]]; do
  echo "Image import is $STATUS: $STATUS_MESSAGE $PROGRESS%"
  sleep 30

  DESCRIBE_RESPONSE=$(aws ec2 describe-export-image-tasks --export-image-task-ids $EXPORT_TASK_ID)
  STATUS=$(echo $DESCRIBE_RESPONSE | jq -r '.ExportImageTasks[0].Status')
  STATUS_MESSAGE=$(echo $DESCRIBE_RESPONSE | jq -r '.ExportImageTasks[0].StatusMessage')
  PROGRESS=$(echo $DESCRIBE_RESPONSE | jq -r '.ExportImageTasks[0].Progress')
done

if [[ "$STATUS" != "completed" ]]; then
    echo "Image import failed: $STATUS - $STATUS_MESSAGE"
    exit 1
fi

echo "Image import for ami $AMI_ID succeeded"

aws s3api put-object-acl --bucket $DST_BUCKET_NAME --key $EXPORTED_IMAGE_KEY --acl public-read
EXPORTED_IMAGE_SHA256=$(curl -s $EXPORTED_IMAGE_URL | sha256sum | cut -d" " -f1)
for dst in "${REPLICAS_SPLIT[@]}"
do
  echo "Copying exported image to $dst"
  aws s3 cp --no-progress --acl public-read $EXPORTED_IMAGE_LOCATION $dst
  echo -n "$EXPORTED_IMAGE_SHA256  $(basename $dst)" > $(basename $dst).sha256
  aws s3 cp --no-progress --acl public-read $(basename $dst).sha256 $dst.sha256
done


#!/usr/bin/env bash

set -x
set -o errexit
set -o nounset
set -o pipefail

BUCKET="${1?Specify second argument - s3 bucket}"

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd -P)"
source "${SCRIPT_ROOT}/build/lib/common.sh"

OS=linux
REPO=client
ARCH=amd64
NAME="kubernetes-sigs/kind"
RELEASE_BRANCH=$(build::eksd_releases::get_release_branch)

echo $(build::common::get_latest_eksa_asset_url $BUCKET $NAME $ARCH $RELEASE_BRANCH)


#!/usr/bin/env bash

set -x
set -o errexit
set -o nounset
set -o pipefail

SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd -P)"
source "${SCRIPT_ROOT}/build/lib/common.sh"

OS=linux
REPO=client
ARCH=amd64
NAME="bin/$OS/$ARCH/kubectl"
RELEASE_BRANCH=$(build::eksd_releases::get_release_branch)

echo $(build::eksd_releases::get_eksd_kubernetes_asset_url $NAME $RELEASE_BRANCH $ARCH)


#!/usr/bin/env bash

set -x
set -o errexit
set -o nounset
set -o pipefail

RELEASES_MANIFEST=$(curl --silent -L $EKSA_RELEASE_MANIFEST_URL)

newest_release_date=0
newest_release_version=""

while IFS=$'\t' read -r date version _; do
    # date is something like '2022-05-05 13:05:34.038243612 +0000 UTC'
    # I can't get `date` to parse this format, so deleting the extra timezone first
    parsed_date=$(date -d "$(echo $date | awk '{print $1,$2,$3}')" +"%s")

    if [ $parsed_date -gt $newest_release_date ];
    then
        newest_release_date=$parsed_date
        newest_release_version=$version
    fi
done < <(echo "$RELEASES_MANIFEST" | yq e '.spec.releases[] | [.date, .version] | @tsv' -)

if [ -z "${newest_release_version}" ]; then
    echo "Not valid release found"
    exit 1
fi

echo -n "$newest_release_version"


#!/usr/bin/env bash

set -x
set -o errexit
set -o nounset
set -o pipefail

LATEST_EKSA_RELEASE_NUMBER=$(curl $EKSA_RELEASE_MANIFEST_URL | yq e '.spec.releases[] | select(.version == '\"$EKSA_VERSION\"') | .number')
PROD_RELEASE_ADMIN_AMI_DESTINATION="s3://$EKSA_PRODUCTION_ARTIFACTS_BUCKET/releases/eks-a/$LATEST_EKSA_RELEASE_NUMBER/artifacts/eks-a-admin-ami/$EKSA_VERSION/eks-anywhere-admin-ami-$EKSA_VERSION-eks-a-$LATEST_EKSA_RELEASE_NUMBER.raw"

echo $PROD_RELEASE_ADMIN_AMI_DESTINATION


#!/usr/bin/env bash

set -x
set -o errexit
set -o nounset
set -o pipefail

EKSA_RELEASE_MANIFEST_S3_URL="${1?Specify first argument - Canonical S3 URL for the EKS-A releases manifest}"
EKSA_RELEASE_MANIFEST_CDN_URL="${2?Specify second argument - CloudFront URL for the EKS-A releases manifest}"

n=0
max_attempts=120
delay=30
while true; do
    LATEST_EKSA_VERSION_S3=$(curl $EKSA_RELEASE_MANIFEST_S3_URL | yq e '.spec.latestVersion' -)
    LATEST_EKSA_VERSION_CLOUDFRONT=$(curl $EKSA_RELEASE_MANIFEST_CDN_URL | yq e '.spec.latestVersion' -)
    [[ "$LATEST_EKSA_VERSION_S3" == "$LATEST_EKSA_VERSION_CLOUDFRONT" ]] && break || {
        if [[ $n -lt $max_attempts ]]; then
            ((n++))
            echo "Older version of release manifest is cached in CloudFront, waiting for cache to be updated - Attempt $n/$max"
            sleep $delay;
        else
            echo "Timeout occured after $n attempts waiting for CloudFront cache to be updated"
            exit 1
        fi
    }
done


#!/bin/bash

set -x
set -o errexit
set -o nounset
set -o pipefail

sudo bash -c 'cat <<'EOF' >> /etc/docker/daemon.json
{
  "log-driver": "journald",
  "log-level": "debug"
}
EOF'

sudo systemctl restart docker --no-block