File: //sbin/oci-yum-repo-mapper
#!/bin/bash
#
# Copyright © 2019 Oracle Corp., Inc. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl
#
function retry_command() {
retry_attempts=5
retry_interval_sec=2
while [ "$retry_attempts" -gt 0 ]; do
command_success=true
"$@" || { command_success=false; }
if [ "$command_success" == false ]; then
((retry_attempts--))
echo "$(date): Error occurred running command $@. Will retry in $retry_interval_sec seconds" >>"$log_file"
sleep $retry_interval_sec
else
break
fi
done
# Check if there is an issue running the command after all retry_attempts
if [ "$command_success" == false ]; then
echo "$(date): ERROR: failed to execute command '$@' (Retried $retry_attempts times)" >>"$log_file"
return 1
fi
}
function repo_mapper_func() {
first_boot=${1}
mirror_yes=0
pubyum_yes=0
if [[ "$first_boot" == "FirstBoot" ]]; then
String="First Boot"
else
String="Instance Reboot or Service Restart"
fi
# Begin: Process OCI Regions.
# Possibilities:
# a) yum mirror is accessible.
# b) no yum mirror, but public yum is accessible
# c) neither yum mirror nor public yum accessible.
if [[ -n "$imds_realm" ]]; then
# a) Is yum mirror responsive?
if curl -L -sfm 25 https://yum."${region}"."${domain}" &>/dev/null; then
mirror_yes=1
echo ".$region" > $ociregion_file
echo "$domain" > $ocidomain_file
echo "$(date): $String seen: OCI realm detected: $imds_realm. Yum mirror connectivity succeeded. Overwriting $ociregion_file to: .$region. Overwriting $ocidomain_file to: $domain" >> $log_file
# b) No yum mirror. Is public yum accessible?
elif curl -L -sfm 25 https://yum.oracle.com &>/dev/null; then
pubyum_yes=1
echo "" > $ociregion_file
echo "oracle.com" > $ocidomain_file
echo "$(date): $String seen: OCI realm detected: $imds_realm. Yum mirror connectivity failed. Public yum connectivity succeeded. Overwriting $ociregion_file to: \"\". Overwriting $ocidomain_file to: $(cat "$ocidomain_file")" >> $log_file
fi
# c) If both, yum mirror and public yum did not respond
# maybe service gateway not yet setup OR an outage.
# Setup similar to yum mirror available scenario.
if [[ ("$mirror_yes" == 0) && ("$pubyum_yes" == 0) ]]; then
echo ".$region" > $ociregion_file
echo "$domain" > $ocidomain_file
echo "$(date): $String seen: OCI realm detected: $imds_realm. Yum mirror connectivity failed. Public yum connectivity failed. Overwriting $ociregion_file to: .$region. Overwriting $ocidomain_file to: $domain" >> $log_file
fi
# End: Process OCI Regions.
fi
if [[ "$first_boot" == "FirstBoot" ]]; then
if [[ "$pubyum_yes" == 1 ]]; then
# Disable repos that are not available on public yum
rpm -q --quiet ksplice-release-el${ol_version} &&
yum-config-manager --disable ol${ol_version}_ksplice &>/dev/null
rpm -q --quiet oci-included-release-el${ol_version} &&
yum-config-manager --disable ol${ol_version}_oci_included &>/dev/null
else
# Disable the ksplice-uptrack repo if installed.
rpm -q --quiet ksplice-uptrack-release &&
yum-config-manager --disable ksplice-uptrack &>/dev/null
fi
fi
}
# Initialize
log_file=/var/log/yum-repo-mapper.log
region_file=/etc/yum/vars/region
ociregion_file=/etc/yum/vars/ociregion
ocidomain_file=/etc/yum/vars/ocidomain
ol_version=7
# Instance First Boot Tracker
yum_populated=/var/lib/oci-yum-repo-mapper-firstrun
# Dynamically set mirror domain and region from IMDSv2 Attributes
if [[ -f "/sys/class/dmi/id/chassis_asset_tag" ]] && grep -q "OracleCloud.com" /sys/class/dmi/id/chassis_asset_tag; then
imds_domain=$(retry_command curl -H "Authorization:Bearer Oracle" -sfm 25 http://169.254.169.254/opc/v2/instance/ 2>/dev/null | jq -r '.regionInfo.realmDomainComponent')
imds_region=$(retry_command curl -H "Authorization:Bearer Oracle" -sfm 25 http://169.254.169.254/opc/v2/instance/ 2>/dev/null | jq -r '.regionInfo.regionIdentifier')
imds_realm=$(retry_command curl -H "Authorization:Bearer Oracle" -sfm 25 http://169.254.169.254/opc/v2/instance/ 2>/dev/null | jq -r '.regionInfo.realmKey')
fi
# OCI-Region
if [[ -n "$imds_realm" ]]; then
domain="oci.$imds_domain"
region="$imds_region"
ociregion=".$region"
# Non-OCI Region: yum.oracle.com
else
domain="oracle.com"
region=""
ociregion=""
fi
# Instance First boot Processing
if [[ ! -f "$yum_populated" ]]; then
echo "$region" > $region_file
echo "$(date): First boot detected in $imds_realm realm. $region_file set to: $region" >> $log_file
echo "$(date): Metadata derived values: Domain: $imds_domain, Region: $imds_region" >> $log_file
# No OCI region found, fallback to public yum.
if [[ -z "$region" ]]; then
echo "$(date): Null region retrieved from metadata service: $region" >> $log_file
# yum variable ociregion needs to be null to fall back to public yum repo
echo "" > $ociregion_file
echo "$(date): $ociregion_file set to: \"\"" >> $log_file
# yum domain ocidomain should be oracle.com to fall back to public yum repo
echo "oracle.com" > $ocidomain_file
echo "$(date): $ocidomain_file set to: $(cat "$ocidomain_file")" >> $log_file
# Disable repos that are not available on public yum
rpm -q --quiet ksplice-release-el${ol_version} &&
yum-config-manager --disable ol${ol_version}_ksplice &>/dev/null
rpm -q --quiet oci-included-release-el${ol_version} &&
yum-config-manager --disable ol${ol_version}_oci_included &>/dev/null
else
repo_mapper_func "FirstBoot"
fi
# /etc/yum/vars populated
touch "$yum_populated"
# per boot
else
# Do not overwrite the region variables unless the region has changed
# since first boot of the instance or the ociregion variable was previously
# null (having failed the OCI yum mirror connectivity test in first boot.)
# Overwriting region to be null in subsequent reboots of the instance or on
# failure to connect to the OCI yum mirror will result in broken repo URLs
# if the user has enabled any OCI specific repos.
echo "$(date): Instance Reboot or Service restart detected in $imds_realm realm" >> $log_file >> $log_file
echo "$(date): Metadata derived values: Domain: $imds_domain, Region: $imds_region" >> $log_file >> $log_file
if [ -n "$region" ]; then
current_region=""
[ -f "$region_file" ] && current_region=$(cat "$region_file")
current_ociregion=""
[ -f "$ociregion_file" ] && current_ociregion=$(cat "$ociregion_file")
current_ocidomain=""
[ -f "$ocidomain_file" ] && current_ocidomain=$(cat "$ocidomain_file")
# Account for IMDSv2 metadata changes per boot
if [ "$region" != "$current_region" ] || [ "$ociregion" != "$current_ociregion" ] || [ "$domain" != "$current_ocidomain" ] || [ -z "$current_ociregion" ]; then
echo "$region" > $region_file
echo "$(date): Service restart or instance reboot detected. Overwriting $region_file to: $region" >> $log_file
# Function to determine the yum settings.
repo_mapper_func "Reboot"
fi
fi
fi
echo "$(date): Instance set to: " >> $log_file
echo "$(date): Domain: $(cat "$ocidomain_file")" >> $log_file
echo "$(date): Region: $(cat "$region_file")" >> $log_file
echo "$(date): Ociregion: $(cat "$ociregion_file")" >> $log_file
echo "$(date): oci-yum-repo-mapper service done: $(date)" >> $log_file