Mauricio
Mauricio

Reputation: 621

GCP / gcloud : Your app may not have more than N versions - how to remove old versions automatically?

While doing new deploy:

gcloud beta app deploy app_stage.yaml

We've got this error:

ERROR: (gcloud.beta.app.deploy) INVALID_ARGUMENT: Your app may not have more than 210 versions. Please delete one of the existing versions before trying to create a new version.

After deleting some versions manually, it worked again.

Does anybody know how to limit each service to work with N least versions automatically? That is, automatically delete version N+1 after new one is created.

Upvotes: 0

Views: 780

Answers (1)

DazWilkin
DazWilkin

Reputation: 40071

There is not but it should be relatively (!?) straightforward to code a solution.

Importantly, test the solution exhaustively before use so that you don't accidently delete an important version in case of unexpected errors; you may want to consider some behavior that, for example, only deletes a version if it's not serving traffic, if there are currently 210 versions and if the version to be deleted is some significant number of days old.

For better error handling, I'd prefer to use a Google SDK for this (and something like Go or Python) but for ease here's some bash pseudocode:

NOTE I don't have an App Engine app deployed and so what follows is from memory.

DO NOT RUN THIS CODE IN PRODUCTION

deploy.sh:

# Env
PROJECT=...

# Do nothing unless you have to
gcloud app deploy \
--project=${PROJECT}

# Failed?
if [ $? -ne 0 ]
then
  # Did it fail because there are 210 versions?
  # Perhaps you could simply parse the previous command's error?
  # Enumerate the list of versions with name and status into a bash array
  VERSIONTIMESTAMPS=($(\
    gcloud app versions list \
    --sort-by="LAST_DEPLOYED" \
    --format="csv[no-heading](id,version.createTime,version.servingStatus)" \
    --project=${PROJECT}))
  # If there are 210
  if [ "${#VERSIONTIMESTAMPS[@]}" -eq 210 ]
  then
    # We're interested in the oldest (either 0, 209) depending on sort
    VERSIONTIMESTAMP=${VERSIONTIMESTAMPS[0]}
    # Extract VERSION, TIMESTAMP and STATUS
    IFS=, read VERSION TIMESTAMP STATUS <<< ${VERSIONTIMESTAMP}
    # Ensure it's STOPPED
    if [ "${STATUS}" == "STOPPED" ]
    then
      CREATED=$(date +%s --date=${TIMESTAMP})
      NOW=$(date +%s)
      DIFF=$((${NOW}-${CREATED}))
      # Seconds to Days
      DAYS=$((${DIFF}/3600/24))
      if [ "${DAYS}" -gt 30 ]
      then
        # There are 210 versions
        # This version is STOPPED
        # The version is older than 30 days
        echo "Deleting: ${VERSION}"
        gcloud app versions delete ${VERSION} \
        --project=${PROJECT}
        # Try the deploy again
        gcloud app deploy \
        --project=${PROJECT}
     fi
    fi
  fi
fi

Upvotes: 2

Related Questions