|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# Script to publish (mirror) container images and helm charts to staging registry. |
| 4 | +# |
| 5 | + |
| 6 | +set -euo pipefail |
| 7 | + |
| 8 | +test "${MDB_BASH_DEBUG:-0}" -eq 1 && set -x |
| 9 | + |
| 10 | +source scripts/dev/set_env_context.sh |
| 11 | +source scripts/funcs/printing |
| 12 | + |
| 13 | +BASE_REPO_URL="268558157000.dkr.ecr.us-east-1.amazonaws.com/dev" |
| 14 | +STAGING_BASE_URL="quay.io/mongodb/staging" |
| 15 | + |
| 16 | +if [[ $# -ne 2 ]]; then |
| 17 | + echo "The tool mirrors images built in any given evg patch id (or latest) from ${BASE_REPO_URL} to ${STAGING_BASE_URL}" |
| 18 | + echo "It publishes helm oci image of the helm chart with chart version \"<prerelease helm version>-<version_id>\"" |
| 19 | + echo "Usage: $0 <prerelease helm version> <version_id>" |
| 20 | + echo "Example: $0 1.4.0-prerelease 68b1a853973bae0007d5eaa0" |
| 21 | + echo "" |
| 22 | + exit 1 |
| 23 | +fi |
| 24 | + |
| 25 | +helm_chart_version_prefix="$1" |
| 26 | +operator_version="$2" |
| 27 | +search_version=${3:-"latest"} |
| 28 | + |
| 29 | +helm_chart_version="${helm_chart_version_prefix}-${operator_version}" |
| 30 | + |
| 31 | +get_arch_digest() { |
| 32 | + local image="$1" |
| 33 | + local arch="$2" |
| 34 | + local manifest_json |
| 35 | + manifest_json=$(docker buildx imagetools inspect --raw "${image}" 2>/dev/null || echo '{}') |
| 36 | + |
| 37 | + local media_type |
| 38 | + media_type=$(echo "$manifest_json" | jq -r '.mediaType // empty') |
| 39 | + |
| 40 | + if [[ "$media_type" == *"manifest.list"* ]]; then |
| 41 | + # this is a multi-arch manifest |
| 42 | + local arch_digest |
| 43 | + arch_digest=$(echo "$manifest_json" | jq -r ".manifests[] | select(.platform.architecture == \"${arch}\" and .platform.os == \"linux\") | .digest") |
| 44 | + |
| 45 | + if [[ -n "$arch_digest" && "$arch_digest" != "null" ]]; then |
| 46 | + echo "$arch_digest" |
| 47 | + return 0 |
| 48 | + fi |
| 49 | + elif [[ "${arch}" == "amd64" ]]; then |
| 50 | + # otherwise it must be a single-arch (image) manifest, so we return it only if we ask for amd64 |
| 51 | + local arch_digest |
| 52 | + arch_digest="sha256:$(echo -n "$manifest_json" | sha256)" |
| 53 | + echo "$arch_digest" |
| 54 | + fi |
| 55 | + |
| 56 | + echo "" |
| 57 | + return 0 |
| 58 | +} |
| 59 | + |
| 60 | +process_image() { |
| 61 | + local source_image="$1" |
| 62 | + local target_image="$2" |
| 63 | + |
| 64 | + echo " Processing ${source_image}..." |
| 65 | + |
| 66 | + local digest_arm64 |
| 67 | + local digest_amd64 |
| 68 | + digest_arm64=$(get_arch_digest "${source_image}" arm64) |
| 69 | + digest_amd64=$(get_arch_digest "${source_image}" amd64) |
| 70 | + |
| 71 | + if [[ -n "${digest_amd64}" ]]; then |
| 72 | + docker pull "${source_image}@${digest_amd64}" |
| 73 | + docker tag "${source_image}@${digest_amd64}" "${target_image}-amd64" |
| 74 | + docker push "${target_image}-amd64" |
| 75 | + fi |
| 76 | + |
| 77 | + if [[ -n "${digest_arm64}" ]]; then |
| 78 | + docker pull "${source_image}@${digest_arm64}" |
| 79 | + docker tag "${source_image}@${digest_arm64}" "${target_image}-arm64" |
| 80 | + docker push "${target_image}-arm64" |
| 81 | + fi |
| 82 | + |
| 83 | + docker manifest create "${target_image}" ${digest_amd64:+--amend ${target_image}-amd64} ${digest_arm64:+--amend ${target_image}-arm64} |
| 84 | + docker manifest push "${target_image}" |
| 85 | +} |
| 86 | + |
| 87 | +publish_images() { |
| 88 | + local names=() |
| 89 | + local sources=() |
| 90 | + local destinations=() |
| 91 | + |
| 92 | + operator_images=( |
| 93 | + "mongodb-kubernetes" |
| 94 | + "mongodb-kubernetes-database" |
| 95 | + "mongodb-kubernetes-init-appdb" |
| 96 | + "mongodb-kubernetes-init-database" |
| 97 | + "mongodb-kubernetes-init-ops-manager" |
| 98 | + "mongodb-kubernetes-readinessprobe" |
| 99 | + "mongodb-kubernetes-operator-version-upgrade-post-start-hook" |
| 100 | + ) |
| 101 | + |
| 102 | + if [[ -n "${search_version}" ]]; then |
| 103 | + names+=("mongodb-search") |
| 104 | + sources+=("901841024863.dkr.ecr.us-east-1.amazonaws.com/mongot-community/rapid-releases:${search_version}") |
| 105 | + destinations+=("${STAGING_BASE_URL}/mongodb-search:${search_version}") |
| 106 | + fi |
| 107 | + |
| 108 | + for image in "${operator_images[@]}"; do |
| 109 | + names+=("${image}") |
| 110 | + sources+=("${BASE_REPO_URL}/${image}:${operator_version}") |
| 111 | + destinations+=("${STAGING_BASE_URL}/${image}:${helm_chart_version}") |
| 112 | + done |
| 113 | + |
| 114 | + echo "Starting Docker image re-tagging and publishing to staging..." |
| 115 | + echo "Version ID: ${operator_version}" |
| 116 | + echo "Source repository: ${BASE_REPO_URL}" |
| 117 | + echo "Target repository: ${STAGING_BASE_URL}" |
| 118 | + echo "" |
| 119 | + |
| 120 | + for i in "${!names[@]}"; do |
| 121 | + process_image "${sources[$i]}" "${destinations[$i]}" |
| 122 | + done |
| 123 | + |
| 124 | + echo "=== SUMMARY ===" |
| 125 | + echo "All images have been successfully re-tagged and pushed to staging!" |
| 126 | + echo "" |
| 127 | + echo "Images processed:" |
| 128 | + for i in "${!names[@]}"; do |
| 129 | + echo " ${names[$i]}: ${sources[$i]} -> ${destinations[$i]}" |
| 130 | + done |
| 131 | +} |
| 132 | + |
| 133 | +update_helm_values() { |
| 134 | + scripts/evergreen/release/update_helm_values_files.py |
| 135 | + yq eval ".version = \"${helm_chart_version}\"" -i helm_chart/Chart.yaml |
| 136 | + echo "Updated helm_chart/Chart.yaml version to: ${helm_chart_version}" |
| 137 | + |
| 138 | + yq eval \ |
| 139 | + ".registry.operator = \"${STAGING_BASE_URL}\" | |
| 140 | + .registry.database = \"${STAGING_BASE_URL}\" | |
| 141 | + .registry.initDatabase = \"${STAGING_BASE_URL}\" | |
| 142 | + .registry.initOpsManager = \"${STAGING_BASE_URL}\" | |
| 143 | + .registry.initAppDb = \"${STAGING_BASE_URL}\" | |
| 144 | + .registry.appDb = \"${STAGING_BASE_URL}\" | |
| 145 | + .registry.versionUpgradeHook = \"${STAGING_BASE_URL}\" | |
| 146 | + .registry.readinessProbe = \"${STAGING_BASE_URL}\" |
| 147 | + " -i helm_chart/values.yaml |
| 148 | + echo "Updated helm_chart/values.yaml registry to: ${STAGING_BASE_URL}" |
| 149 | +} |
| 150 | + |
| 151 | +prepare_helm_oci_image() { |
| 152 | + mkdir -p tmp |
| 153 | + helm package helm_chart -d tmp/ |
| 154 | +} |
| 155 | + |
| 156 | +push_helm_oci_image() { |
| 157 | + export HELM_REGISTRY_CONFIG=~/.docker/config.json |
| 158 | + helm push "tmp/mongodb-kubernetes-${helm_chart_version}.tgz" "oci://${STAGING_BASE_URL}/helm-chart" |
| 159 | +} |
| 160 | + |
| 161 | +update_release_json() { |
| 162 | + if [[ ! -f "release.json" ]]; then |
| 163 | + echo "Error: release.json file not found" |
| 164 | + exit 1 |
| 165 | + fi |
| 166 | + |
| 167 | + echo "Updating release.json with versions..." |
| 168 | + |
| 169 | + # Update operator and init versions |
| 170 | + jq --arg version "${helm_chart_version}" \ |
| 171 | + --arg registry "${STAGING_BASE_URL}" \ |
| 172 | + '.mongodbOperator = $version | |
| 173 | + .initDatabaseVersion = $version | |
| 174 | + .initOpsManagerVersion = $version | |
| 175 | + .initAppDbVersion = $version | |
| 176 | + .databaseImageVersion = $version' \ |
| 177 | + release.json > release.json.tmp && mv release.json.tmp release.json |
| 178 | + |
| 179 | + # Update search community version |
| 180 | + jq --arg searchVersion "${search_version}" \ |
| 181 | + --arg searchRepo "${STAGING_BASE_URL}" \ |
| 182 | + --arg searchImageName "mongodb-search" \ |
| 183 | + '.search.community.repo = $searchRepo | |
| 184 | + .search.community.name = $searchImageName | |
| 185 | + .search.community.version = $searchVersion' \ |
| 186 | + release.json > release.json.tmp && mv release.json.tmp release.json |
| 187 | + |
| 188 | + echo "Updated release.json with:" |
| 189 | + echo " - Operator versions: ${helm_chart_version}" |
| 190 | + echo " - Search community version: ${MDB_SEARCH_COMMUNITY_VERSION}" |
| 191 | +} |
| 192 | + |
| 193 | +revert_changes_to_local_files() { |
| 194 | + echo "Reverting generated/updated files: helm_chart/ public/ config/ release.json" |
| 195 | + git checkout -- helm_chart/ public/ config/ release.json |
| 196 | +} |
| 197 | + |
| 198 | +publish_images |
| 199 | +update_release_json |
| 200 | +update_helm_values |
| 201 | +prepare_helm_oci_image |
| 202 | +push_helm_oci_image |
| 203 | +revert_changes_to_local_files |
0 commit comments