Skip to content

Commit

Permalink
Merge pull request #1474 from Nordix/peppi-lotta/get-latest-release-f…
Browse files Browse the repository at this point in the history
…rom-goproxy

🌱 Get latest releases with GOPROXY
  • Loading branch information
metal3-io-bot authored Dec 3, 2024
2 parents 0b07f57 + 97d770e commit b745d52
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 109 deletions.
13 changes: 8 additions & 5 deletions 03_launch_mgmt_cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ source lib/releases.sh
# shellcheck disable=SC1091
source lib/network.sh

# Default CAPI_CONFIG_DIR to $HOME/.config directory if XDG_CONFIG_HOME not set
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
export CAPI_CONFIG_DIR="${CONFIG_DIR}/cluster-api"
export IRONIC_HOST="${CLUSTER_BARE_METAL_PROVISIONER_HOST}"
export IRONIC_HOST_IP="${CLUSTER_BARE_METAL_PROVISIONER_IP}"
export REPO_IMAGE_PREFIX="quay.io"
Expand Down Expand Up @@ -468,8 +471,8 @@ function update_component_image(){
function patch_clusterctl(){

pushd "${CAPM3PATH}"
mkdir -p "${CAPI_CONFIG_FOLDER}"
touch "${CAPI_CONFIG_FOLDER}"/clusterctl.yaml
mkdir -p "${CAPI_CONFIG_DIR}"
touch "${CAPI_CONFIG_DIR}"/clusterctl.yaml

# At this point the images variables have been updated with update_images
# Reflect the change in components files
Expand All @@ -488,9 +491,9 @@ function patch_clusterctl(){
update_capm3_imports
make release-manifests

rm -rf "${CAPI_CONFIG_FOLDER}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
mkdir -p "${CAPI_CONFIG_FOLDER}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
cp out/*.yaml "${CAPI_CONFIG_FOLDER}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
rm -rf "${CAPI_CONFIG_DIR}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
mkdir -p "${CAPI_CONFIG_DIR}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
cp out/*.yaml "${CAPI_CONFIG_DIR}"/overrides/infrastructure-metal3/"${CAPM3RELEASE}"
popd
}

Expand Down
134 changes: 35 additions & 99 deletions lib/releases.sh
Original file line number Diff line number Diff line change
@@ -1,120 +1,56 @@
#!/bin/bash

function get_latest_release() {

# fail when release_path is not passed
local release_path="${1:?no release path is given}"

# set url to get 100 releases from first page
local url="${release_path}?per_page=100&page=1"

# fail when release is not passed
# Requires parameters url and version. An optional parameter can be given to
# exclude some versions.
# Example usage:
# get_latest_release_from_goproxy "https://proxy.golang.org/sigs.k8s.io/cluster-api/@v/list" "v1.8." "beta|rc|pre|alpha"
get_latest_release_from_goproxy() {
local proxuUrl="${1:?no release path is given}"
local release="${2:?no release given}"
local exclude="${3:-}"

set +x

if [ -z "${GITHUB_TOKEN:-}" ]; then
response=$(curl -si "${url}")
# This gets the latest release
if [[ -z "${exclude}" ]]; then
release_tag=$(curl -s "${proxuUrl}" | sort -rV | grep -m1 "^${release}")
else
response=$(curl -si "${url}" -H "Authorization: token ${GITHUB_TOKEN}")
fi

# Divide response to headers and body
response_headers=$(echo "${response}" | awk 'BEGIN {RS="\r\n\r\n"} NR==1 {print}')
if ! echo "${response_headers}" | grep -q 'Connection established'; then
response_body=$(echo "${response}" | awk 'BEGIN {RS="\r\n\r\n"} NR==2 {print}')
else
response_headers=$(echo "${response}" | awk 'BEGIN {RS="\r\n\r\n"} NR==2 {print}')
response_body=$(echo "${response}" | awk 'BEGIN {RS="\r\n\r\n"} NR==3 {print}')
fi

# get the last page of releases from headers
last_page=$(echo "${response_headers}" | grep '^link:' | sed -e 's/^link:.*page=//g' -e 's/>.*$//g')

# This gets the latest release as vx.y.z or vx.y.z-rc.0, including any version with a suffix starting with - , for example -rc.0
# The order is exactly as released in Github.
# Downside is that selecting official releases only isn't possible, while pre-release
# selection is possible given specific enough prefix, like v1.3.0-pre
release_tag=$(echo "${response_body}" | jq ".[].name" -r | grep -E "${release}" -m 1)

# If release_tag is not found in the first page(100 releases), this condition checks from second to last_page
# until release_tag is found
if [ -z "${release_tag}" ]; then
for current_page in $(seq 2 "${last_page}"); do
url="${release_path}?per_page=100&page=${current_page}"
if [ -z "${GITHUB_TOKEN:-}" ]; then
release_tag=$(curl -sL "${url}" | jq ".[].name" -r | grep -E "${release}" -m 1)
else
release_tag=$(curl -sL "${url}" -H "Authorization: token ${GITHUB_TOKEN}" | jq ".[].name" -r | grep -E "${release}" -m 1)
fi
# if release_tag found break the loop
if [ -n "${release_tag}" ]; then
break
fi
done
# prune based on exluded values given in the command
release_tag=$(curl -s "${proxuUrl}" | sort -rV | grep -vE "${exclude}" | grep -m1 "${release}")
fi

set -x

# if release_tag is not found
if [ -z "${release_tag}" ]; then
echo "Error: release is not found from ${release_path}" >&2
if [[ -z "${release_tag}" ]]; then
echo "Error: release is not found from ${proxuUrl}" >&2
exit 1
else
echo "${release_tag}"
fi
echo "${release_tag}"
}

# CAPM3, CAPI and BMO release path
CAPIRELEASEPATH="{https://api.github.com/repos/${CAPI_BASE_URL:-kubernetes-sigs/cluster-api}/releases}"
CAPIGOPROXY="https://proxy.golang.org/sigs.k8s.io/cluster-api/@v/list"

# Extract release version from release-branch name
if [[ "${CAPM3RELEASEBRANCH}" == release-* ]]; then
CAPM3_RELEASE_PREFIX="${CAPM3RELEASEBRANCH#release-}"
else
CAPM3_RELEASE_PREFIX=""
fi

# CAPM3, CAPI and BMO releases
if [ "${CAPM3RELEASEBRANCH}" = "release-1.6" ]; then
# 1.6.99 points to the head of the release-1.6 branch. Local override for CAPM3 is created for this version.
export CAPM3RELEASE="v1.6.99"
export CAPIRELEASE="${CAPIRELEASE:-$(get_latest_release "${CAPIRELEASEPATH}" "v1.6.")}"
elif [ "${CAPM3RELEASEBRANCH}" = "release-1.7" ]; then
# 1.7.99 points to the head of the release-1.7 branch. Local override for CAPM3 is created for this version.
export CAPM3RELEASE="v1.7.99"
export CAPIRELEASE="${CAPIRELEASE:-$(get_latest_release "${CAPIRELEASEPATH}" "v1.7.")}"
elif [ "${CAPM3RELEASEBRANCH}" = "release-1.8" ]; then
# 1.8.99 points to the head of the release-1.8 branch. Local override for CAPM3 is created for this version.
export CAPM3RELEASE="v1.8.99"
export CAPIRELEASE="${CAPIRELEASE:-$(get_latest_release "${CAPIRELEASEPATH}" "v1.8.")}"
# Fetch CAPI version that coresponds to CAPM3_RELEASE_PREFIX release version
if [[ "${CAPM3_RELEASE_PREFIX}" =~ ^(1\.6|1\.7|1\.8)$ ]]; then
export CAPM3RELEASE="v${CAPM3_RELEASE_PREFIX}.99"
CAPI_RELEASE_PREFIX="v${CAPM3_RELEASE_PREFIX}."
else
# 1.9.99 points to the head of the main branch of CAPM3. Local override for CAPM3 is created for this version.
export CAPM3RELEASE="v1.9.99"
export CAPIRELEASE="${CAPIRELEASE:-$(get_latest_release "${CAPIRELEASEPATH}" "v1.8.")}"
CAPI_RELEASE_PREFIX="v1.8."
fi

export CAPIRELEASE="${CAPIRELEASE:-$(get_latest_release_from_goproxy "${CAPIGOPROXY}" "${CAPI_RELEASE_PREFIX}")}"
CAPIBRANCH="${CAPIBRANCH:-${CAPIRELEASE}}"

# On first iteration, jq might not be installed
if [[ "$CAPIRELEASE" == "" ]]; then
command -v jq &>/dev/null && echo "Failed to fetch CAPI release from Github" && exit 1
fi

if [[ "$CAPM3RELEASE" == "" ]]; then
command -v jq &>/dev/null && echo "Failed to fetch CAPM3 release from Github" && exit 1
if [[ -z "${CAPIRELEASE}" ]]; then
echo "Failed to fetch CAPI release from GOPROXY"
exit 1
fi

# Set CAPI_CONFIG_FOLDER variable according to CAPIRELEASE minor version
# Starting from CAPI v1.5.0 version cluster-api config folder location has changed
# to XDG_CONFIG_HOME folder.
# Following code defines the cluster-api config folder location according to CAPI
# release version

# TODO(Sunnatillo): Following condition should be removed when CAPM3 v1.4 reaches EOL
# NOTE(Sunnatillo): When CAPM3 v1.4 reaches EOL CAPI_CONFIG_FOLDER variable can be removed
# for the sake of reducing variables

version_string="${CAPIRELEASE#v}"
IFS='.' read -r _ minor _ <<< "$version_string"

if [ "$minor" -lt 5 ]; then
export CAPI_CONFIG_FOLDER="${HOME}/.cluster-api"
else
# Default CAPI_CONFIG_FOLDER to $HOME/.config folder if XDG_CONFIG_HOME not set
CONFIG_FOLDER="${XDG_CONFIG_HOME:-$HOME/.config}"
export CAPI_CONFIG_FOLDER="${CONFIG_FOLDER}/cluster-api"
if [[ -z "${CAPM3RELEASE}" ]]; then
echo "Failed to fetch CAPM3 release from GOPROXY"
exit 1
fi
6 changes: 3 additions & 3 deletions tests/roles/run_tests/tasks/generate_templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
- name: Deploy clusterctl variables to clusterctl config
ansible.builtin.blockinfile:
block: "{{lookup('ansible.builtin.template', '{{ CRS_PATH }}/clusterctl-vars.yaml')}}"
path: "{{ CAPI_CONFIG_FOLDER }}/clusterctl.yaml"
path: "{{ CAPI_CONFIG_DIR }}/clusterctl.yaml"
create: yes
state: present

- name: Generate clusterctl cluster template
template:
src: "{{ CRS_PATH }}/cluster-template-{{ item }}.yaml"
dest: "{{CAPI_CONFIG_FOLDER }}/overrides/infrastructure-metal3/{{ CAPM3RELEASE }}/cluster-template-{{ item }}.yaml"
dest: "{{CAPI_CONFIG_DIR }}/overrides/infrastructure-metal3/{{ CAPM3RELEASE }}/cluster-template-{{ item }}.yaml"
with_items:
- cluster
- controlplane
Expand All @@ -38,7 +38,7 @@
clusterctl_var: "{{ 'generate' if CAPI_VERSION == 'v1beta1' else 'config' }}"
shell: >
clusterctl {{ clusterctl_var }} cluster {{ CLUSTER_NAME }}
--from {{CAPI_CONFIG_FOLDER }}/overrides/infrastructure-metal3/{{ CAPM3RELEASE }}/cluster-template-{{ item }}.yaml
--from {{CAPI_CONFIG_DIR }}/overrides/infrastructure-metal3/{{ CAPM3RELEASE }}/cluster-template-{{ item }}.yaml
--kubernetes-version {{ KUBERNETES_VERSION }}
--control-plane-machine-count={{ CONTROL_PLANE_MACHINE_COUNT }}
--worker-machine-count={{ WORKER_MACHINE_COUNT }}
Expand Down
2 changes: 1 addition & 1 deletion tests/roles/run_tests/vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ NAMEPREFIX: "{{ lookup('env', 'NAMEPREFIX') | default('baremetal-operator', true
CRS_PATH: "{{ metal3_dir }}/tests/roles/run_tests/templates"
TEMP_GEN_DIR: "{{ metal3_dir }}/tests/roles/run_tests/files/manifests"
EPHEMERAL_CLUSTER: "{{ lookup('env', 'EPHEMERAL_CLUSTER') | default('kind', true) }}"
CAPI_CONFIG_FOLDER: "{{ lookup('env', 'CAPI_CONFIG_FOLDER') | default('$HOME/.config/cluster-api', true) }}"
CAPI_CONFIG_DIR: "{{ lookup('env', 'CAPI_CONFIG_DIR') | default('$HOME/.config/cluster-api', true) }}"
CLUSTER_APIENDPOINT_HOST: "{{ lookup('env', 'CLUSTER_APIENDPOINT_HOST') }}"
CLUSTER_APIENDPOINT_PORT: "{{ lookup('env', 'CLUSTER_APIENDPOINT_PORT') | default(6443, true) }}"
CLUSTER_APIENDPOINT_IP: "{{ lookup('env', 'CLUSTER_APIENDPOINT_IP') }}"
Expand Down
2 changes: 1 addition & 1 deletion vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ assured that they are persisted.
| DHCP_HOSTS | A list of `;` separated dhcp-host directives for dnsmasq | e.g. `00:20:e0:3b:13:af;00:20:e0:3b:14:af` | |
| DHCP_IGNORE | A set of tags on hosts to be ignored by dnsmasq | e.g. `tag:!known` | |
| ENABLE_NATED_PROVISIONING_NETWORK | A single boolean to configure whether provisioner and provisioning networks are in separate subnets and there is NAT betweend them or not | "true","false" | "false" |
| CAPI_CONFIG_FOLDER | Cluster API config folder path | `$HOME/.cluster-api/`, `$XDG_CONFIG_HOME/cluster-api`, `$HOME/.config/cluster-api` | `$HOME/.config/cluster-api` |
| CAPI_CONFIG_DIR | Cluster API config directory path | `$HOME/.cluster-api/`, `$XDG_CONFIG_HOME/cluster-api`, `$HOME/.config/cluster-api` | `$HOME/.config/cluster-api` |
| IPA_BASEURI | IPA downloader will download IPA from this url | | https://tarballs.opendev.org/openstack/ironic-python-agent/dib |
| IPA_BRANCH | The last part of the name of the IPA archive | | master |
| IPA_FLAVOR | The middle part of the name of the IPA archive | | centos9 |
Expand Down

0 comments on commit b745d52

Please sign in to comment.