Skip to content

Commit

Permalink
Merge pull request #2507 from Cray-HPE/feature/embedded-repo
Browse files Browse the repository at this point in the history
CASMINST-6507 Rework embedded repo
  • Loading branch information
mtupitsyn authored Jul 5, 2023
2 parents fd0932c + 4c1b35f commit f17a76a
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 477 deletions.
10 changes: 3 additions & 7 deletions Jenkinsfile.github
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pipeline {
steps {
withCredentials([usernamePassword(credentialsId: credentialsId, usernameVariable: 'ARTIFACTORY_USER', passwordVariable: 'ARTIFACTORY_TOKEN')]) {
sh """
./assets.sh
./hack/verify-assets.sh
"""
}
}
Expand All @@ -98,12 +98,8 @@ pipeline {
steps {
withCredentials([usernamePassword(credentialsId: credentialsId, usernameVariable: 'ARTIFACTORY_USER', passwordVariable: 'ARTIFACTORY_TOKEN')]) {
sh """
./hack/verify-rpm-index.sh \
rpm/cray/csm/sle-15sp2/index.yaml \
rpm/cray/csm/sle-15sp3/index.yaml \
rpm/cray/csm/sle-15sp4/index.yaml \
rpm/cray/csm/sle-15sp5/index.yaml \
rpm/cray/csm/noos/index.yaml
./hack/verify-rpm-index.sh rpm/cray/csm/*/index.yaml
./hack/embedded-repo.sh --validate
"""
}
}
Expand Down
81 changes: 1 addition & 80 deletions assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ KERNEL_VERSION='5.14.21-150400.24.66-default'
# by doing a zypper search for the corresponding kernel-default-debuginfo package
# in the SLE-Module-Basesystem update_debug repo
# zypper --plus-repo=https://${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}@artifactory.algol60.net/artifactory/sles-mirror/Updates/SLE-Module-Basesystem/15-SP4/x86_64/update_debug se -s kernel-default-debuginfo
KERNEL_DEFAULT_DEBUGINFO_VERSION="${KERNEL_VERSION/-default/}.1.${NCN_ARCH}"
KERNEL_DEFAULT_DEBUGINFO_VERSION="${KERNEL_VERSION/-default/}.1"

# The image ID may not always match the other images and should be defined individually.
KUBERNETES_IMAGE_ID=5.1.20
Expand Down Expand Up @@ -73,82 +73,3 @@ for arch in "${CN_ARCH[@]}"; do
done

HPE_SIGNING_KEY=https://arti.hpc.amslabs.hpecorp.net/artifactory/dst-misc-stable-local/SigningKeys/HPE-SHASTA-RPM-PROD.asc

set -exo pipefail

# usage: cmd_retry <cmd> <arg1> ...
#
# Run the specified command until it passes or until it fails too many times
function cmd_retry
{
local -i attempt
# For now I'm hard coding these values, but it would be easy to make them into function
# arguments in the future, if desired
local -i max_attempts=10
local -i sleep_time=12
attempt=1
while [ true ]; do
# We redirect to stderr just in case the output of this command is being piped
echo "Attempt #$attempt to run: $*" 1>&2
if "$@" ; then
return 0
elif [ $attempt -lt $max_attempts ]; then
echo "Sleeping ${sleep_time} seconds before retry" 1>&2
sleep ${sleep_time}
attempt=$(($attempt + 1))
continue
fi
echo "ERROR: Unable to get $url even after retries" 1>&2
return 1
done
echo "PROGRAMMING LOGIC ERROR: This line should never be reached" 1>&2
exit 1
}

if [ -z "${ARTIFACTORY_USER}" -o -z "${ARTIFACTORY_TOKEN}" ]; then
echo "Missing authentication information for image download. Please set ARTIFACTORY_USER and ARTIFACTORY_TOKEN environment variables."
exit 1
fi
# Verify assets exist
for url in "${PIT_ASSETS[@]}"; do cmd_retry curl -sfSLI -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "$url"; done
for url in "${KUBERNETES_ASSETS[@]}"; do cmd_retry curl -sfSLI -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "$url"; done
for url in "${STORAGE_CEPH_ASSETS[@]}"; do cmd_retry curl -sfSLI -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "$url"; done
for arch in "${CN_ARCH[@]}"; do
for url in $(eval echo \${COMPUTE_${arch}_ASSETS[@]}); do cmd_retry curl -sfSLI -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "$url"; done
done

cmd_retry curl -sfSLI "$HPE_SIGNING_KEY"

# Verify that kubernetes and other supplementary images, shipped with node-image, are
# present in manifest (and, cnsequently, in Nexus). Versions, shipped with node image,
# are exposed as image file properties in Artifactory.
ROOTDIR=$(dirname $0)
KUBERNETES_VERSIONS_JSON="$(mktemp)"
trap "rm -f '${KUBERNETES_VERSIONS_JSON}'" EXIT
shopt -s expand_aliases
alias yq="${ROOTDIR}/vendor/github.com/Cray-HPE/shasta-cfg/utils/bin/$(uname | awk '{print tolower($0)}')/yq"
cmd_retry curl -sSL -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" -o "${KUBERNETES_VERSIONS_JSON}" "${KUBERNETES_ASSETS[0]/artifactory\/csm-images/artifactory\/api\/storage\/csm-images}?properties"
declare -A KUBERNETES_IMAGES=(
[KUBERNETES_VERSION]="k8s.gcr.io/kube-apiserver k8s.gcr.io/kube-controller-manager k8s.gcr.io/kube-proxy k8s.gcr.io/kube-scheduler"
[WEAVE_VERSION]="docker.io/weaveworks/weave-kube docker.io/weaveworks/weave-npc"
[MULTUS_VERSION]="ghcr.io/k8snetworkplumbingwg/multus-cni"
[COREDNS_VERSION]="k8s.gcr.io/coredns"
)
error=0
for KEY in "${!KUBERNETES_IMAGES[@]}"; do
for IMAGE_TAG in $(jq -r ".properties.\"csm.versions.${KEY}\"[]?" "${KUBERNETES_VERSIONS_JSON}"); do
for IMAGE_NAME in ${KUBERNETES_IMAGES[${KEY}]}; do
if yq read "${ROOTDIR}/docker/index.yaml" "\"artifactory.algol60.net/csm-docker/stable\".images.\"${IMAGE_NAME}\".[*]" | grep -F -x -q "${IMAGE_TAG}"; then
echo "INFO: Image ${IMAGE_NAME}:${IMAGE_TAG} is found in manifest."
else
echo "ERROR: Image ${IMAGE_NAME}:${IMAGE_TAG} is not found in manifest."
error=1
fi
done
done
done
if [ $error -eq 1 ]; then
echo "ERROR: Assets components image validation failed. Not all container images for components, shipped with node image,"
echo "ERROR: are listed in manifest (see above). Add missing container images to docker/images.yaml, or use different node image."
exit 1
fi
17 changes: 5 additions & 12 deletions build/images/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,27 @@ SHELL=/usr/bin/env bash -euo pipefail
# Get the process ID of the process running Make
MAKEPID:= $(shell echo $$PPID)

all: index.txt chartmap
all: index.txt chartmap.csv

index.txt: $(manifests_images) docker/index.txt
index.txt: docker/index.txt $(manifests_images)
cat $^ | sort -u | parallel -j 75% --retries 5 --halt-on-error soon,fail=100% ./inspect.sh | sort -u > $@

# Kill (SIGINT) the make PGID to short-circuit parallel makes (fail fast)
manifests/%.txt: ../../manifests/%.yaml get_base pull_images
manifests/%.txt: ../../manifests/%.yaml
@mkdir -p $(@D)
./extract.sh $< | sort -u > $@ || kill -INT -$(MAKEPID)

docker/index.txt: ../../docker/index.yaml
@mkdir -p $(@D)
../../hack/list-images.py $< | sort -u > $@

get_base:
./get_base.sh

pull_images:
./pull_images.sh
../../hack/list-images.py $< | sort -u > $@

.PHONY: chartmap

chartmap: index.txt
chartmap.csv: index.txt
@echo "manifest,chart,image" > chartmap.csv
@find ./charts -type f -name chartmap.csv -exec cat {} \; | sort -u >> chartmap.csv

.PHONY: clean

clean:
$(RM) index.txt $(manifests_images) docker/index.txt chartmap.csv base_index.txt

135 changes: 135 additions & 0 deletions hack/embedded-repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env bash
set -e -o pipefail

if ! ([ $# -eq 1 ] && [ "$1" == "--validate" ]) && [ $# -ne 2 ]; then
echo "Manage RPM repo from PIT/NCN package lists (so called 'embedded repo')."
echo "Lists of packages and repo configurations, installed onto NCN images, "
echo "are expected to be published along with NCN image files as:"
echo ""
echo " csm-images/stable/<ncn_type>/<ncn_version>/installed-<ncn_version>-<arch>.packages"
echo " csm-images/stable/<ncn_type>/<ncn_version>/installed.deps-<ncn_version>-<arch>.packages"
echo " csm-images/stable/<ncn_type>/<ncn_version>/installed-<ncn_version>-<arch>.repos"
echo ""
echo "With --validate, validate presence of all RPM packages in repositories."
echo "Otherwise, download RPMs into <target_dir>, filtering out those which are alredy in <duplicates_dir>,"
echo "and calculate RPM metadata."
echo "Usage: $0 [--validate] | [<target_dir> <duplicates_dir>]"
exit 1
fi

TMPDIR=$(mktemp -d)
trap "rm -fr '$TMPDIR'" EXIT

ROOTDIR=$(realpath "${ROOTDIR:-$(dirname "${BASH_SOURCE[0]}")/..}")
source "${ROOTDIR}/assets.sh"
source "${ROOTDIR}/vendor/github.hpe.com/hpe/hpc-shastarelm-release/lib/release.sh"

if [ -z "${ARTIFACTORY_USER}" ] || [ -z "${ARTIFACTORY_TOKEN}" ]; then
echo "Missing authentication information for image download. Please set ARTIFACTORY_USER and ARTIFACTORY_TOKEN environment variables."
exit 1
fi

echo "Downloading package lists ..."
for LIST_TYPE in installed installed.deps; do
for LIST_URL in \
"pre-install-toolkit/${PIT_IMAGE_ID}/${LIST_TYPE}-${PIT_IMAGE_ID}-${NCN_ARCH}.packages" \
"kubernetes/${KUBERNETES_IMAGE_ID}/${LIST_TYPE}-${KUBERNETES_IMAGE_ID}-${NCN_ARCH}.packages" \
"storage-ceph/${STORAGE_CEPH_IMAGE_ID}/${LIST_TYPE}-${STORAGE_CEPH_IMAGE_ID}-${NCN_ARCH}.packages"; do
curl -Ss -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "https://artifactory.algol60.net/artifactory/csm-images/stable/${LIST_URL}"
done
done | tr '=' '-' | sort -u > "${TMPDIR}/ncn.rpm-list"

# Explicitly append kernel-default and kernel-default-debuginfo packages to rpm list
if [ -n "$KERNEL_DEFAULT_DEBUGINFO_VERSION" ]; then
echo "kernel-default-${KERNEL_DEFAULT_DEBUGINFO_VERSION}" >> "${TMPDIR}/ncn.rpm-list"
echo "kernel-default-debuginfo-${KERNEL_DEFAULT_DEBUGINFO_VERSION}" >> "${TMPDIR}/ncn.rpm-list"
fi

echo "List of packages for embedded repo:"
cat "${TMPDIR}/ncn.rpm-list" | sed 's/^/ /'

echo "Downloading repo configs ..."
for REPOS_URL in \
"pre-install-toolkit/${PIT_IMAGE_ID}/installed-${PIT_IMAGE_ID}-${NCN_ARCH}.repos" \
"kubernetes/${KUBERNETES_IMAGE_ID}/installed-${KUBERNETES_IMAGE_ID}-${NCN_ARCH}.repos" \
"storage-ceph/${STORAGE_CEPH_IMAGE_ID}/installed-${STORAGE_CEPH_IMAGE_ID}-${NCN_ARCH}.repos"; do
curl -Ss -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "https://artifactory.algol60.net/artifactory/csm-images/stable/${REPOS_URL}"
done | grep -E '^baseurl=https://' \
| sed -e 's/^baseurl=//' \
| sed -e 's|https://[^@]*@|https://|' \
| sed -e 's/\?auth=basic$//' \
| sort -u > "${TMPDIR}/ncn.repo-list.releasever"

# Append update_debug repos, where kernel-default-debuginfo package is provided
if [ -n "$KERNEL_DEFAULT_DEBUGINFO_VERSION" ]; then
echo 'https://artifactory.algol60.net/artifactory/sles-mirror/Updates/SLE-Module-Legacy/${releasever_major}-SP${releasever_minor}/${basearch}/update_debug' >> "${TMPDIR}/ncn.repo-list.releasever"
fi

# Try repos for SLES 15 SP3 and SP4
(
cat "${TMPDIR}/ncn.repo-list.releasever" \
| sed -e "s/\${basearch}/${NCN_ARCH}/g" \
| sed -e "s/\${releasever_major}/15/g" \
| sed -e "s/\${releasever_minor}/4/g" \
| sed -e "s/\${releasever}/15.4/g"
cat "${TMPDIR}/ncn.repo-list.releasever" \
| sed -e "s/\${basearch}/${NCN_ARCH}/g" \
| sed -e "s/\${releasever_major}/15/g" \
| sed -e "s/\${releasever_minor}/3/g" \
| sed -e "s/\${releasever}/15.3/g"
) | sort -u > "${TMPDIR}/ncn.repo-list.unverified"

# Filter out non-existent repos and generate directory names for rpm-index input
echo -ne > "${TMPDIR}/ncn.repo-list"
cat "${TMPDIR}/ncn.repo-list.unverified" | while read url; do
if curl -I -Ss -f -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" "$url/repodata/repomd.xml" >/dev/null 2>/dev/null; then
dir="${url#https://}"
dir="${dir#artifactory.algol60.net/artifactory/}"
dir="${dir//-mirror/}"
echo "$url" "$dir" >> "${TMPDIR}/ncn.repo-list"
fi
done

echo "List of repositories for embedded repo:"
cat "${TMPDIR}/ncn.repo-list" | sed 's/^/ /'

echo "Building RPM package index ..."
# In validate mode, also produce YAML file, which can be used by setup-nexus.sh script
if [ "${1}" == "--validate" ]; then
mkdir -p "${ROOTDIR}/rpm/embedded"
OUTPUT_FILE="${ROOTDIR}/rpm/embedded/index.yaml"
OUTPUT_FORMAT="YAML"
else
OUTPUT_FILE="${TMPDIR}/embedded.url-list"
OUTPUT_FORMAT="DOWNLOAD_CSV"
fi
export REPOCREDSVAR=$(jq --null-input --arg url "https://artifactory.algol60.net/artifactory/" --arg realm "Artifactory Realm" --arg user "$ARTIFACTORY_USER" --arg password "$ARTIFACTORY_TOKEN" '{($url): {"realm": $realm, "user": $user, "password": $password}}')
# Filtering out conntrack package, because it is not in our repos, and gets into NCN image from local mount during build
(cat "${TMPDIR}/ncn.rpm-list" \
| grep -v conntrack-1-1 \
| docker run -e REPOCREDSVAR --rm -i "${PACKAGING_TOOLS_IMAGE}" rpm-index -c REPOCREDSVAR -v \
--input-format NEVR \
--output-format "${OUTPUT_FORMAT}" \
$(sed -e 's/^/-d /' "${TMPDIR}/ncn.repo-list") \
-
)> "${OUTPUT_FILE}"

if [ "${1}" == "--validate" ]; then
echo "All RPM packages were resolved successfully"
else
TARGET_DIR=$(realpath "${1}")
DUPLICATES_DIR=$(realpath "${2}")
DUPLICATES=$(find "${DUPLICATES_DIR}" -name '*.rpm' -not -wholename "${TARGET_DIR}/*" -exec basename '{}' ';')
cat "${OUTPUT_FILE}" | while IFS="," read -r dir url; do
file=$(basename "${url}")
if echo "${DUPLICATES}" | grep -q -x -F "${file}"; then
echo "Skipping ${file} - already present in ${2}"
else
echo "Downloading ${url} ..."
mkdir -p "${TARGET_DIR}/${dir}"
curl -Ss -f -u "${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN}" -o "${TARGET_DIR}/${dir}/${file}" "${url}"
fi
done
# Create repository for node image RPMs
createrepo "${TARGET_DIR}"
fi
Loading

0 comments on commit f17a76a

Please sign in to comment.