#!/bin/sh
#
# $NetBSD: ec2_init,v 1.8 2026/05/16 20:59:59 jschauma Exp $
#
# PROVIDE: ec2_init
# REQUIRE: NETWORKING
# BEFORE:  LOGIN

$_rc_subr_loaded . /etc/rc.subr

name="ec2_init"
rcvar=${name}
start_cmd="ec2_init"
stop_cmd=":"

HOSTNAME_URL="hostname"

IMDS_IP="169.254.169.254"
IMDS_IPv6="fd00:ec2::254"

CLOUD_TYPE=EC2
case "$(/sbin/sysctl -n machdep.dmi.chassis-asset-tag 2>/dev/null)" in
OracleCloud*)
	CLOUD_TYPE=OCI
	;;
esac

EC2_USER="ec2-user"
case ${CLOUD_TYPE} in
EC2)
	EC2_USER="ec2-user"
	METADATA_URL_PATH="latest/meta-data/"
	SSH_KEY_URL="public-keys/0/openssh-key"
	;;
OCI)
	EC2_USER="opc"
	METADATA_URL_PATH="opc/v1/instance/"
	SSH_KEY_URL="metadata/ssh_authorized_keys"
	;;
esac


ec2_hostname()
{
	# hostname may already be set via /etc/rc.d/network
	if [ -n "$hostname" ] || [ -f /etc/myname ]; then
		return
	fi

	(
	umask 022
	HOSTNAME=$(ftp -o - -q 2 "${METADATA_URL}${HOSTNAME_URL}")
	if [ -n "$HOSTNAME" ]; then
		echo "Setting ${CLOUD_TYPE} hostname: ${HOSTNAME}"
		echo "$HOSTNAME" > /etc/myname
		hostname "$HOSTNAME"
		break
	fi
	)
}

ec2_init()
{
	ec2_metadata
	ec2_hostname
	ec2_user
	ec2_random_seed
}


ec2_metadata()
{
	local imds="${IMDS_IP}"

	# It may be 5-10 seconds for the metadata service
	# to become reachable.  Try IPv4 first (AWS does not
	# enable the IPv6 metadata endpoint by default), then
	# IPv6 and use whichever works.
	try=0
	while [ $((try++)) -lt 20 ]
	do
		ftp -o /dev/null -q 2 http://${IMDS_IP}/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
		if [ $? -eq 0 ]; then
			break
		fi

		ftp -o /dev/null -q 2 http://[${IMDS_IPv6}]/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
		if [ $? -eq 0 ]; then
			imds="[${IMDS_IPv6}]"
			break
		fi

		echo "Metadata service not available yet (try $try / 20)..."
		sleep 1
	done

	METADATA_URL="http://${imds}/${METADATA_URL_PATH}"

	SSH_KEY_FILE="/home/${EC2_USER}/.ssh/authorized_keys"

	OS_METADATA_URL="http://${imds}/openstack/latest/meta_data.json"
}

ec2_newuser()
{
	echo "Creating ${CLOUD_TYPE} user account ${EC2_USER}"
	useradd -g users -G wheel,operator -m "${EC2_USER}"
}

ec2_random_seed()
{
	# May contain a "random_seed".
	OS_METADATA="$(ftp -o - -q 2 ${OS_METADATA_URL} 2>/dev/null)"
	if echo "$OS_METADATA" | grep -q random_seed; then
		echo "$OS_METADATA" | extract_random_seed |
		    base64 -di >> /dev/urandom
	fi
}

ec2_user()
{
	# create cloud user
	id "${EC2_USER}" >/dev/null 2>&1 || ec2_newuser

	# fetch the public key from the metadata service
	EC2_SSH_KEY=$(ftp -o - -q 2 "${METADATA_URL}${SSH_KEY_URL}")

	if [ -n "$EC2_SSH_KEY" ]; then
		# A key pair is associated with this instance, add it
		# to EC2_USER's 'authorized_keys' file
		mkdir -p $(dirname "$SSH_KEY_FILE")
		chown "${EC2_USER}:users" $(dirname "$SSH_KEY_FILE")
		touch "$SSH_KEY_FILE"
		chown "${EC2_USER}:users" "$SSH_KEY_FILE"
		cd $(dirname "$SSH_KEY_FILE")

		grep -q "$EC2_SSH_KEY" "$SSH_KEY_FILE"
		if [ $? -ne 0 ]; then
			echo "Setting ${CLOUD_TYPE} SSH public key for user ${EC2_USER}: ${EC2_SSH_KEY##* }"
			echo "$EC2_SSH_KEY" >> "$SSH_KEY_FILE"
		fi
	fi
}

extract_random_seed()
{
	sed -n -e '/random_seed/s/.*"random_seed": *"\([A-Za-z0-9+/=]*\)".*/\1/p'
}

load_rc_config $name
run_rc_command "$1"
