--- /dev/null
+#!/bin/sh
+
+VERBOSITY=1
+TEMP_D=""
+CONFIG=/etc/cirros-init/ds-ec2
+MDURL="http://169.254.169.254/2009-04-04"
+NAME="${0##*/}"
+
+. ${CIRROS_SHLIB:=/lib/cirros/shlib} ||
+ { echo "failed to read ${CIRROS_SHLIB}" 1>&2; exit 1; }
+
+error() { echo "$@" 1>&2; }
+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
+
+Usage() {
+ cat <<EOF
+Usage: ${0##*/} mode output_d
+
+ Datasource for EC2 metadata service
+ Requires network.
+EOF
+}
+
+mdget() {
+ ec2metadata "--url=$MDURL" "$@"
+}
+
+cleanup() {
+ [ -z "${TMPF}" -o ! -f "$TMPF" ] || rm -f "${TMPF}"
+}
+
+search_local() {
+ local out_d="$1"
+ local i="" max="" iid="" uptime=""
+ [ -d "$out_d" ] || mkdir -p "$out_d" ||
+ { error "failed to create output dir"; return 1; }
+ TMPF="${out_d}/tmpf"
+
+ trap cleanup EXIT
+
+ debug 1 "checking $MDURL/instance-id"
+ i=0
+ MAX_TRIES=${MAX_TRIES:-20}
+ SLEEP_TIME=${SLEEP_TIME:-2}
+
+ max=${MAX_TRIES}
+ while [ $i -lt ${max} ] && i=$(($i+1)); do
+ read uptime idle < /proc/uptime
+ if iid=$(mdget --instance-id 2>/dev/null); then
+ [ "${iid#i-}" != "${iid}" ] && break
+ debug 1 "failed $i/${max}: up ${uptime}. iid had '${iid}'"
+ else
+ debug 1 "failed $i/${max}: up ${uptime}. request failed"
+ fi
+ sleep $SLEEP_TIME
+ done
+
+ if [ -n "${iid}" ]; then
+ debug 1 "successful after ${i}/${max} tries: up ${uptime}. iid=${iid}"
+ else
+ error "failed to read iid from metadata. tried ${max}";
+ return 0
+ fi
+
+ local keys="" key=""
+ keys="public-keys instance-id ami-launch-index instance-type local-ipv4
+ public-ipv4 hostname local-hostname user-data
+ block-device-mappings public-hostname availability-zone"
+ mkdir -p "${out_d}/data"
+ for key in $keys; do
+ mdget "--${key}" > "${out_d}/data/${key}" ||
+ debug 1 "warning: no ec2 metadata for $key"
+ done
+
+ local fix="" t="" f=""
+ for fix in ami-launch-index:launch-index; do
+ f="${fix%:*}"
+ t="${fix#*:}"
+ [ -f "${out_d}/data/$f" -a ! -f "${out_d}/data/$t" ] || continue
+ ln -sf "$f" "${out_d}/data/$t" ||
+ fail "failed to link $f to ${out_d}/data/t"
+ done
+
+ echo 0 > "$out_d/result"
+ return
+}
+
+apply() {
+ # ec2 datasource does nothing for apply
+ local mode="$1" data_d="$2"
+ return 0
+}
+
+short_opts="hv"
+long_opts="help,verbose"
+getopt_out=$(getopt --name "${0##*/}" \
+ --options "${short_opts}" --long "${long_opts}" -- "$@") &&
+ eval set -- "${getopt_out}" ||
+ bad_Usage
+
+output=""
+
+while [ $# -ne 0 ]; do
+ cur=${1}; next=${2};
+ case "$cur" in
+ -h|--help) Usage ; exit 0;;
+ -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
+ --) shift; break;;
+ esac
+ shift;
+done
+
+[ $# -eq 2 ] || bad_Usage "must provide mode and data dir"
+mode="$1"
+out_d="$2"
+
+[ "$mode" = "net" -o "$mode" = "apply-net" ] || {
+ debug 2 "only supported in mode 'net' or 'apply-net'";
+ exit 0;
+}
+
+[ ! -e "$CONFIG" ] || . "$CONFIG" ||
+ fail "failed to read $CONFIG"
+
+if [ "$mode" = "net" ]; then
+ search_local "$out_d"
+elif [ "$mode" = "apply-net" ]; then
+ apply "$mode" "$out_d"
+else
+ fail "error, unexpected input"
+fi
+
+exit
+# vi: ts=4 noexpandtab