Skip to content

Instantly share code, notes, and snippets.

@jpbochi
Created July 25, 2017 12:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpbochi/17d644b7752fbc3d46e528851ecbe28d to your computer and use it in GitHub Desktop.
Save jpbochi/17d644b7752fbc3d46e528851ecbe28d to your computer and use it in GitHub Desktop.
bash script to lock/unlock resources by using an S3 bucket with file versioning
#!/usr/bin/env bash
set -eu
log () {
echo >&2 "[lock] $@"
}
putLock () {
aws s3api put-object --region $REGION --bucket $BUCKET --key $LOCK_KEY --output text --query 'VersionId'
}
removeLock () {
aws s3api delete-object --region $REGION --bucket $BUCKET --key $LOCK_KEY --version-id $LOCK_VERSION --output text
}
listLockVersions () {
aws s3api list-object-versions --region $REGION --bucket $BUCKET --prefix $LOCK_KEY \
--page-size=3 --max-items=3 \
--query '{deleted:DeleteMarkers[*].{date:LastModified,version:VersionId},versions:Versions[*].{date:LastModified,version:VersionId}}'
}
REGION=${REGION:-us-west-2}
LOCK_URL="${1-}"
if ! echo $LOCK_URL | grep -q '^s3:\/\/[^\/]*\/..*'; then
log "Usage: $0 "'s3://${some-bucket}/${some-lock-file-name}'
exit 1
fi
BUCKET=$(echo $LOCK_URL | sed 's/^s3:\/\///' | sed 's/\/.*//')
LOCK_KEY=$(echo $LOCK_URL | sed 's/^s3:\/\/[^\/]*\///')
log "trying to acquire lock ${LOCK_URL} at ${REGION}..."
LOCK_VERSION=$(putLock)
log "verifying lock handle '${LOCK_VERSION}'..."
VERSIONS=$(listLockVersions)
MOST_RECENT_VERSION=$(echo $VERSIONS | jq '.versions[0].version' --raw-output)
DATE_PREVIOUS=$(echo $VERSIONS | jq '.versions[1].date' --raw-output | sed 's/^null/1970-01-01T00:00:00.000Z/')
DATE_DELETED=$(echo $VERSIONS | jq '.deleted[0].date' --raw-output | sed 's/^null/1970-01-01T00:00:00.000Z/')
if [ "$MOST_RECENT_VERSION" != "$LOCK_VERSION" ]; then
log 'failed. Newer lock found. Cleaning up...'
removeLock >&2
exit 1
elif [ "$DATE_PREVIOUS" \> "$DATE_DELETED" ]; then
log 'failed. Existing lock still valid. Cleaning up...'
removeLock >&2
exit 1
else
log 'acquired. Generating command to unlock it...'
UNLOCK_CMD="aws s3api delete-object --region $REGION --bucket $BUCKET --key $LOCK_KEY --version-id $LOCK_VERSION --output text"
log $UNLOCK_CMD
echo $UNLOCK_CMD
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment