mirror of
				https://github.com/flatcar/scripts.git
				synced 2025-10-31 00:01:03 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			191 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/bin/bash
 | |
| #
 | |
| # Copyright (c) 2024 The Flatcar Maintainers.
 | |
| # Use of this source code is governed by a BSD-style license that can be
 | |
| # found in the LICENSE file.
 | |
| 
 | |
| # >>> This file is supposed to be SOURCED from the repository ROOT. <<<
 | |
| #
 | |
| # garbage_collect_releases() should be called after sourcing.
 | |
| #
 | |
| #  OPTIONAL INPUT
 | |
| #  - Number releases to keep per channel. Defaults to 10.
 | |
| #  - Number of LTS channels to keep. Defaults to 2 (i.e. the current and the previous (deprecated) LTS).
 | |
| #  - DRY_RUN (Env variable). Set to "y" to just list what would be done but not
 | |
| #            actually purge anything.
 | |
| 
 | |
| # Flatcar build cache releases artifacts garbage collector.
 | |
| #  This script removes release artifacts of past releases from the build cache.
 | |
| #  Note that release artifacts are copied to official mirrors upon release, so there's
 | |
| #   no need to keep a copy on the build cache server.
 | |
| 
 | |
| function garbage_collect_releases() {
 | |
|     # Run a subshell, so the traps, environment changes and global
 | |
|     # variables are not spilled into the caller.
 | |
|     (
 | |
|         set -euo pipefail
 | |
| 
 | |
|         _garbage_collect_releases_impl "${@}"
 | |
|     )
 | |
| }
 | |
| # --
 | |
| 
 | |
| function _garbage_collect_releases_impl() {
 | |
|     local keep_per_chan="${1:-10}"
 | |
|     local keep_lts_releases="${2:-2}"
 | |
|     local dry_run="${DRY_RUN:-}"
 | |
| 
 | |
|     echo
 | |
|     echo "Number of versions to keep per channel: '${keep_per_chan}'"
 | |
|     echo "Number of LTS major releases to keep: '${keep_lts_releases}'"
 | |
|     echo
 | |
| 
 | |
|     source ci-automation/ci_automation_common.sh
 | |
|     local sshcmd="$(gen_sshcmd)"
 | |
| 
 | |
|     local keep=$( 
 | |
|         # For some reasons this is set to the empty string in some environments and it makes gawk
 | |
|         #  behave like POSIX awk (i.e. no 'gensub').
 | |
|         unset POSIXLY_CORRECT
 | |
|         curl -s "${RELEASES_JSON_FEED}" \
 | |
|             | jq -r 'keys_unsorted | .[] | match("[0-9]+\\.[0-9]+\\.[0-9]+") | .string' \
 | |
|             | sort -Vr \
 | |
|             | awk -v keep="${keep_per_chan}" -v lts="${keep_lts_releases}" '
 | |
|                 {
 | |
|                     version = $1
 | |
|                     chan_num = gensub("[0-9]+\\.([0-9]+)\\.[0-9]+","\\1","g", version) + 0
 | |
|                     major = gensub("([0-9]+)\\.[0-9]+\\.[0-9]+","\\1","g", version) + 0
 | |
| 
 | |
|                     if (chan_num <= 2) {
 | |
|                         if (chan_count[chan_num] < keep)
 | |
|                             print version
 | |
|                         chan_count[chan_num] = chan_count[chan_num] + 1
 | |
|                     } else {
 | |
|                         if (    (chan_count["lts"][major] < keep) \
 | |
|                              && (length(chan_count["lts"]) <= lts) )
 | |
|                             print version
 | |
|                         chan_count["lts"][major] = chan_count["lts"][major] + 1
 | |
|                     }
 | |
|                 } '
 | |
|     )
 | |
| 
 | |
|     mapfile -t keep_versions <<<"${keep}"
 | |
| 
 | |
|     echo
 | |
|     echo "######## The following version(s) will be kept ########"
 | |
|     if [ "$dry_run" = "y" ] ; then
 | |
|         echo
 | |
|         echo "(NOTE this is just a dry run since DRY_RUN=y)"
 | |
|         echo
 | |
|     fi
 | |
|     printf "%s\n" "${keep_versions[@]}"
 | |
| 
 | |
|     local dir=""
 | |
|     for dir in  "sdk/amd64" \
 | |
|                 "containers" \
 | |
|                 "boards/amd64-usr" \
 | |
|                 "boards/arm64-usr" \
 | |
|                 "images/amd64" \
 | |
|                 "images/arm64" \
 | |
|                 "testing" \
 | |
|                 ; do
 | |
| 
 | |
|         local fullpath="${BUILDCACHE_PATH_PREFIX}/${dir}"
 | |
|         echo
 | |
|         echo "## Processing '${fullpath}'"
 | |
|         echo "---------------------------"
 | |
|         for version in $($sshcmd "${BUILDCACHE_USER}@${BUILDCACHE_SERVER}" \
 | |
|                                  "ls -1 ${BUILDCACHE_PATH_PREFIX}/${dir} | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'"); do
 | |
|             local o_fullpath="${fullpath}/${version}"
 | |
| 
 | |
|             # Go through all deletion candidate versions in directory
 | |
|             #   skip if candidate version is marked for keeping OR if it's a new release about to be published
 | |
|             #   or if it ships an SDK used by a version in the keep list.
 | |
|             if printf "%s\n" "${keep_versions[@]}" \
 | |
|                | { unset POSIXLY_CORRECT ; awk -v candidate_version="${version}" -v path="${dir}" '
 | |
|                 BEGIN {
 | |
|                     # Candidate version (from build cache directory) that was passed in candidate_version variable
 | |
|                     candidate_major = gensub("([0-9]+)\\.[0-9]+\\.[0-9]+","\\1","g", candidate_version) + 0
 | |
|                     candidate_minor = gensub("[0-9]+\\.([0-9]+)\\.[0-9]+","\\1","g", candidate_version) + 0
 | |
|                     candidate_patch = gensub("[0-9]+\\.[0-9]+\\.([0-9]+)","\\1","g", candidate_version) + 0
 | |
|                     ret = 1
 | |
|                 }
 | |
| 
 | |
|                 {
 | |
|                     # The whole keep versions list is piped into AWK; match the candidate (build cache) version agains each entry.
 | |
| 
 | |
|                     keep_list_entry = $0
 | |
|                     if (keep_list_entry == candidate_version) {
 | |
|                         print ""
 | |
|                         print "## Skipping " candidate_version " because it is in the keep list."
 | |
|                         ret = 0
 | |
|                         exit
 | |
|                     }
 | |
| 
 | |
|                     keep_list_major = gensub("([0-9]+)\\.[0-9]+\\.[0-9]+","\\1","g", keep_list_entry) + 0
 | |
|                     keep_list_minor = gensub("[0-9]+\\.([0-9]+)\\.[0-9]+","\\1","g", keep_list_entry) + 0
 | |
|                     keep_list_patch = gensub("[0-9]+\\.[0-9]+\\.([0-9]+)","\\1","g", keep_list_entry) + 0
 | |
| 
 | |
|                     if ( (path == "sdk/amd64") && (candidate_major == keep_list_major) ) {
 | |
|                         print ""
 | |
|                         print "## Skipping " candidate_version " in " path " because it contains the SDK for release " keep_list_entry " in keep list."
 | |
|                         ret = 0
 | |
|                         exit
 | |
|                     }
 | |
| 
 | |
|                     # keep list piped into AWK is sorted (descending), so the very first (i.e. highest) version on top is the most recent Alpha release
 | |
|                     if (latest_alpha_major == "")
 | |
|                         latest_alpha_major = keep_list_major
 | |
| 
 | |
|                     if (candidate_major > latest_alpha_major) {
 | |
|                         print ""
 | |
|                         print "## Skipping " candidate_version " because major version is higher than the latest Alpha (" latest_alpha_major ") in keep list."
 | |
|                         print "(I.e. this is an unpublished new Alpha release)"
 | |
|                         ret = 0
 | |
|                         exit
 | |
|                     }
 | |
| 
 | |
|                     if ((candidate_major == keep_list_major) && (candidate_minor > keep_list_minor)) {
 | |
|                         print ""
 | |
|                         print "## Skipping " candidate_version " because major version is in keep list and minor version is higher than the latest release."
 | |
|                         print "(I.e. this is an unpublished channel progression " keep_list_entry " -> " candidate_version ")"
 | |
|                         ret = 0
 | |
|                         exit
 | |
|                     }
 | |
| 
 | |
|                     if ((candidate_major == keep_list_major) && (candidate_minor == keep_list_minor) && (candidate_patch > keep_list_patch)) {
 | |
|                         print ""
 | |
|                         print "## Skipping " version " because major and minor versions are in keep list and patch version is higher than the latest release."
 | |
|                         print "(I.e. this is an unpublished new patch release " keep_list_entry " -> " candidate_version ")"
 | |
|                         ret = 0
 | |
|                         exit
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 END {
 | |
|                     exit ret
 | |
|                 }' ; } then
 | |
|                 continue
 | |
|             fi
 | |
| 
 | |
|             echo
 | |
|             echo "## Removing version '${version}' in '${o_fullpath}'"
 | |
|             echo
 | |
| 
 | |
|             echo "## The following files will be removed ##"
 | |
|             $sshcmd "${BUILDCACHE_USER}@${BUILDCACHE_SERVER}" \
 | |
|                 "ls -la ${o_fullpath} || true"
 | |
| 
 | |
|             if [ "$dry_run" != "y" ] ; then
 | |
|                 set -x
 | |
|                 $sshcmd "${BUILDCACHE_USER}@${BUILDCACHE_SERVER}" \
 | |
|                     "rm -rf ${o_fullpath} || true"
 | |
|                 set +x
 | |
|             else
 | |
|                 echo "## (DRY_RUN=y so not doing anything) ##"
 | |
|             fi
 | |
|         done
 | |
|     done
 | |
| }
 | |
| # --
 |