| #!/usr/bin/env bash |
| |
| # Copyright (c) 2021-2022, NVIDIA CORPORATION. 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. |
| |
| # Dependencies: |
| # regctl |
| # |
| |
| function assert_usage() { |
| cat >&2 << EOF |
| Incorrect arguments: $* |
| $(basename "${BASH_SOURCE[0]}") DIST-ARCH |
| DIST: The distribution. |
| ARCH: The architecture. |
| |
| Environment Variables |
| ARTIFACTORY_TOKEN: must contain an auth token. [required] |
| LIB_TAG: optional package tag. |
| CI_COMMIT_REF_NAME: provided by CI/CD system. |
| CI_COMMIT_SHA: provided by CI/CD system. |
| EOF |
| exit 1 |
| } |
| |
| SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../scripts && pwd )" |
| PROJECT_ROOT="$( cd "${SCRIPTS_DIR}/.." && pwd )" |
| |
| source "${SCRIPTS_DIR}"/utils.sh |
| |
| if [[ $# -ne 1 ]]; then |
| assert_usage "$@" |
| fi |
| |
| DISTARCH=$1 |
| ARTIFACTORY_PATH=$2 |
| DIST=${DISTARCH%-*} |
| ARCH=${DISTARCH##*-} |
| |
| CURL=${CURL:-curl} |
| |
| if [[ -z "${DIST}" || -z "${ARCH}" ]]; then |
| echo "ERROR: Distro and Architecture must be specified." >&2 |
| assert_usage "$@" |
| fi |
| |
| if [[ -z "${ARTIFACTORY_PATH}" ]]; then |
| echo "ERROR: Package repo must be specified." >&2 |
| assert_usage "$@" |
| fi |
| |
| if [[ -z "${ARTIFACTORY_TOKEN}" ]]; then |
| echo "ERROR: ARTIFACTORY_TOKEN must be defined." >&2 |
| assert_usage "$@" |
| fi |
| |
| # TODO: accept PACKAGES_DIR as a command-line argument |
| : "${ARTIFACTS_DIR="${PROJECT_ROOT}/artifacts"}" |
| : "${PACKAGES_DIR="${ARTIFACTS_DIR}/packages"}" |
| |
| eval $(${SCRIPTS_DIR}/get-component-versions.sh) |
| |
| # Returns the key=value property if the value isn't empty |
| # Prepends with ";" if needed |
| set_prop_value() { |
| local key=$1 |
| local value=$2 |
| if [ -n "${value}" ]; then |
| if [ -z "${PROPS}" ]; then |
| echo "${key}=${value}" |
| else |
| echo ";${key}=${value}" |
| fi |
| fi |
| } |
| |
| process_props() { |
| local dist=$1 |
| local arch=$2 |
| local file=$3 |
| local component_name="${file%%.*}" |
| component_name="${component_name%-*}" |
| local pkg_type="$(package_type $dist)" |
| |
| ## Component owner is free to define these |
| # PROPS+=$(set_prop_value "version" "${VERSION}") |
| # PROPS+=$(set_prop_value "lws_version" "${LWS_VER}") |
| # PROPS+=$(set_prop_value "platform" "${DISTARCH}") |
| |
| # TODO: Use `git describe` to get this information if it's not available. |
| PROPS+=$(set_prop_value "changelist" "${CI_COMMIT_SHA}") |
| PROPS+=$(set_prop_value "branch" "${CI_COMMIT_REF_NAME}") |
| |
| # PROPS+=$(set_prop_value "category" "utils") |
| # PROPS+=$(set_prop_value "platform" "${DISTARCH}") |
| |
| # Gitlab variables to expose |
| for var in CI_PROJECT_ID CI_PIPELINE_ID CI_JOB_ID CI_JOB_URL CI_PROJECT_PATH; do |
| if [ -n "${!var}" ]; then |
| PROPS+=$(set_prop_value "${var}" "${!var}") |
| fi |
| done |
| |
| # We also set the package-specific properties to allow this to be used for other artifactory repositories |
| PROPS+=$(set_prop_value "${pkg_type}.distribution" "${dist}") |
| PROPS+=$(set_prop_value "${pkg_type}.architecture" "${arch}") |
| PROPS+=$(set_prop_value "${pkg_type}.component" "${component_name}") |
| } |
| |
| # Uploads file ARTIFACTORY_PATH |
| # Relies on global variables: DIST, ARCH, ARTIFACTORY_TOKEN, ARTIFACTORY_PATH |
| upload_file() { |
| local dist=$1 |
| local arch=$2 |
| local file=$3 |
| |
| # TODO: These should be set by envvars |
| local artifactory_host="urm.nvidia.com" |
| local artifactory_repo="$(get_artifactory_repository $dist)" |
| |
| if [ ! -r "${file}" ]; then |
| echo "ERROR: File not found or not readable: ${file}" |
| exit 1 |
| fi |
| |
| local PROPS |
| process_props "${dist}" "${arch}" "${file}" |
| |
| # Collect sum |
| SHA1_SUM=$(sha1sum -b "${file}" | awk '{ print $1 }') |
| |
| url="https://${artifactory_host}/artifactory/${artifactory_repo}/${dist}/${arch}/$(basename "${file}")" |
| # NOTE: The URL to set the properties through the API is: |
| # "https://${artifactory_host}/artifactory/api/storage/${artifactory_repo}/${dist}/${arch}/$(basename ${file})" |
| |
| echo "Uploading ${file} to ${url}" |
| if ! ${CURL} -f \ |
| -H "X-JFrog-Art-Api: ${ARTIFACTORY_TOKEN}" \ |
| -H "X-Checksum-Sha1: ${SHA1_SUM}" \ |
| ${file:+-T ${file}} -X PUT \ |
| "${url};${PROPS}" ; |
| then |
| echo "ERROR: upload file failed: ${file}" |
| exit 1 |
| fi |
| } |
| |
| function push-artifactory() { |
| local dist="$1" |
| local arch="$2" |
| |
| source="${ARTIFACTS_DIR}/packages/${dist}/${arch}" |
| |
| find "${source}" -maxdepth 1 | while read -r f ; do |
| upload_file "$dist" "$arch" "$f" |
| done |
| } |
| |
| # TODO: use this to adapt as a general purpose command-line tool |
| # case "${COMMAND}" in |
| # set) |
| # set_props |
| # ;; |
| # upload) |
| # if [ -z "${UPLOAD_FILE}" ]; then |
| # echo "ERROR: Upload package filename must be set using -f" |
| # usage |
| # fi |
| # |
| # upload_file |
| # ;; |
| # *) |
| # echo "ERROR: Invalid command ${COMMAND}" |
| # usage |
| # ;; |
| # esac |
| |
| push-artifactory "${DIST}" "${ARCH}" |