Skip to content

Instantly share code, notes, and snippets.

@whitebrandy
Last active January 20, 2023 12:16
Show Gist options
  • Save whitebrandy/b55ef7c018b0c2dc2daf1ab19d3d34e6 to your computer and use it in GitHub Desktop.
Save whitebrandy/b55ef7c018b0c2dc2daf1ab19d3d34e6 to your computer and use it in GitHub Desktop.
Script to create a cloud image using the builder_image API
#!/usr/bin/env bash
GREEN='\033[0;32m'
RED='\033[0;31m'
NOCOLOR='\033[0m'
WARNMSG="Could not generate a valid access token, it happens... just rerun the command or get a new offline token"
warnmsg () {
printf "${RED} $1"
printf "${NOCOLOR}"
echo;
}
msg () {
printf "${GREEN} $1"
printf "${NOCOLOR}"
echo;
}
[ "$DEBUG" == 'true' ] && set -x
ARGC=$#
usage() {
if [ $ARGC -le 0 ]; then
warnmsg "USAGE: $(basename $0) <offline_token from https://access.redhat.com/management/api> <image name> <packages to install>(optional)"
exit 0
fi
}
offline_token="$1"
image_name="$2"
packages="${@:3}"
distro="rhel-87"
TMPDIR=$(mktemp -d)
format_package_string() {
package_string=""
local firstentry=true
if [ "$packages" != "" ]
then
PACKAGE_STRING="\"customizations\": {
\"packages\": ["
for entry in $packages
do
if ! $firstentry
then
PACKAGE_STRING="$PACKAGE_STRING",
else
firstentry=false
fi
PACKAGE_STRING="$PACKAGE_STRING
\"$entry\""
done
#add the rest
PACKAGE_STRING="$PACKAGE_STRING
]
},"
fi
}
format_request_string() {
FILE=${TMPDIR}/request.json
cat > ${FILE} << EOF
{
"image_name": "$image_name",
"distribution": "$distro",
$PACKAGE_STRING
"image_requests": [
{
"image_type": "guest-image",
"architecture": "x86_64",
"upload_request": {
"type": "aws.s3",
"options": {}
}
}
]
}
EOF
}
cleanup() {
rm -rf $TMPDIR
}
required_packages() {
prereqs="jq curl wget"
for package in $prereqs
do
if ! which $package 2>&1 > /dev/null; then
warnmsg "$package is not installed, required packages are: $prereqs"
cleanup
exit 1
fi
done
}
get_access_token() {
msg "Getting a access token using your offline token"
access_token=$(curl --silent --request POST --data grant_type=refresh_token --data client_id=rhsm-api --data refresh_token=$offline_token https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token | jq -r .access_token)
[ "$access_token" = null ] && warnmsg "Could not generate a valid access token, it happens... just rerun the command or get a new offline token" && cleanup && exit 1
}
validate_access_token() {
msg "Validating access token..."
validate=$(curl --silent --header "Authorization: Bearer $access_token" https://console.redhat.com/api/image-builder/v1/openapi.json | jq .)
if ! echo "$validate" | grep /api/image-builder 2>&1 > /dev/null
then
warnmsg "Validating failed, $WARNMSG" && cleanup && exit 1
fi
}
send_request() {
compose_id=$(curl --silent --request POST --header "Authorization: Bearer $access_token" --header "Content-Type: application/json" --data @$FILE https://console.redhat.com/api/image-builder/v1/compose | jq -r .id)
[ "$compose_id" = null ] && warnmsg "Image generation request failed... please run the command again or get a new offline token and retry" &&\
cleanup && exit 1
}
download_image() {
url=$(curl --silent --header "Authorization: Bearer $access_token" "https://console.redhat.com/api/image-builder/v1/composes/$compose_id" | jq -r ".image_status | .upload_status | .options | .url")
curl -o `pwd`/$image_name $url
if stat $image_name 2>&1 > /dev/null
then
msg "Image downloaded to `readlink -f $image_name`"
else
warnmsg "Image download failed from url: $url"
cleanup
exit 1
fi
}
wait_for_status_change() {
while true
do
status=$(curl --silent --header "Authorization: Bearer $access_token" "https://console.redhat.com/api/image-builder/v1/composes/$compose_id" | jq -r ".image_status | .status")
if [ "$status" = "$1" ]
then
printf '.' > /dev/tty
sleep 3
else
echo
break
fi
done
}
wait_for_image() {
compose_id=$(curl --silent --request POST --header "Authorization: Bearer $access_token" --header "Content-Type: application/json" --data @$FILE https://console.redhat.com/api/image-builder/v1/compose | jq -r .id)
[ "$compose_id" = null ] && warnmsg "Could not submit build request, it happens... just rerun the command or get a new offline token and repeat" && cleanup && exit 1
status=$(curl --silent --header "Authorization: Bearer $access_token" "https://console.redhat.com/api/image-builder/v1/composes/$compose_id" | jq -r ".image_status | .status")
while true
do
case $status in
pending)
msg "Build with compose id $compose_id pending"
wait_for_status_change "pending"
;;
building)
msg "Building image with compose_id: $compose_id"
msg "Go to https://console.redhat.com/beta/insights/image-builder for the web ui"
wait_for_status_change "building"
;;
success)
msg "Build completed"
download_image
break
;;
*)
warnmsg "Invalid building status : $status"
warnmsg "$WARNMSG"
cleanup
exit 1
;;
esac
done
}
usage
required_packages
format_package_string
format_request_string
get_access_token
validate_access_token
send_request
wait_for_image
cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment