Merge pull request #722 from bgilbert/oracle

oem/oracle: Add some scripts to manage images/instances
This commit is contained in:
Benjamin Gilbert 2017-08-14 14:04:05 -07:00 committed by GitHub
commit 91f9af2f9e
4 changed files with 258 additions and 0 deletions

40
oem/oracle/common.sh Normal file
View File

@ -0,0 +1,40 @@
# Get the tenancy ID, which is also the ID of the root compartment.
# Unconditionally uses the first profile in the conffile.
get_tenancy_id() {
local line=$(grep -m 1 "^tenancy=" "$HOME/.oraclebmc/config")
echo "${line#*=}"
}
# Pick an availability domain by listing them and choosing the first one.
get_availability_domain() {
local compartment="$1"
bmcs iam availability-domain list \
-c "${compartment}" | jq -r ".data[0].name"
}
# Pick a subnet ID by picking the first VCN and then the first subnet in the
# specified availability domain.
get_subnet_id() {
local compartment="$1"
local availability_domain="$2"
local vcn=$(bmcs network vcn list \
-c "${compartment}" | jq -r ".data[0].id")
bmcs network subnet list \
-c "${compartment}" \
--vcn-id "${vcn}" | jq -r ".data[] | select(.[\"availability-domain\"] == \"${availability_domain}\").id"
}
# Get the object storage namespace ID.
get_namespace_id() {
bmcs os ns get | jq -r ".data"
}
# Get the ID of some arbitrary image. Useful for iPXE boot, which requires
# an image ID but doesn't seem to use it.
get_an_image_id() {
local compartment="$1"
bmcs compute image list \
-c "${compartment}" \
--operating-system "CentOS" \
--operating-system-version 7 | jq -r '.data[0].id'
}

35
oem/oracle/get-console-output Executable file
View File

@ -0,0 +1,35 @@
#!/bin/bash
set -e -o pipefail
# Parse args
usage="Usage: $0 [args] -i instance-id
Options:
-i INSTANCE-ID Instance ID
-h This ;-)
"
while getopts "i:h" OPTION
do
case "${OPTION}" in
i) instance_id="${OPTARG}" ;;
h) echo "${usage}"; exit 2 ;;
*) exit 2 ;;
esac
done
if [[ -z "${instance_id}" ]]; then
echo "Instance ID is required." >&2
exit 2
fi
id=$(bmcs compute console-history capture --instance-id "${instance_id}" | jq -r .data.id)
trap 'bmcs compute console-history delete --instance-console-history-id "${id}" --force' EXIT
while true; do
state=$(bmcs compute console-history get --instance-console-history-id "${id}" | jq -r '.data["lifecycle-state"]')
if [[ "${state}" = SUCCEEDED ]]; then
break
fi
sleep 1
done
# Default length is 10 KB; maximum is 1 MB. Request at least that much.
bmcs compute console-history get-content --instance-console-history-id "${id}" --file - --length 2000000

108
oem/oracle/launch-instance Executable file
View File

@ -0,0 +1,108 @@
#!/bin/bash
set -e -o pipefail
. common.sh
# Initialize vars
compartment=$(get_tenancy_id)
availability_domain=$(get_availability_domain "${compartment}")
image_id=$(get_an_image_id "${compartment}")
subnet_id=$(get_subnet_id "${compartment}" "${availability_domain}")
name=
shape="BM.Standard1.36"
ipxe=0
ignition=
baseurl="http://alpha.release.core-os.net/amd64-usr/current"
bucket_base="users.developer.core-os.net/$USER/bmcs"
kargs=
# Parse args
usage="Usage: $0 [args] -n name
Options:
-c COMPARTMENT Compartment ID (default: ${compartment})
-a AVAIL-DOMAIN Availability domain ID (default: ${availability_domain})
-n NAME Instance name
-s SHAPE Instance shape (default: ${shape})
-S SUBNET-ID Subnet ID to use (default: ${subnet_id})
-i IGNITION Path to Ignition config
-p Boot with iPXE
-I IMAGE-ID Image ID to use; only relevant for non-iPXE (default: ${image_id})
-b BASEURL URL to the image mirror; only relevant for iPXE (default: ${baseurl})
-B BUCKET-BASE GS bucket and relative path for iPXE script (default: ${bucket_base})
-k ARGS Additional kernel command line arguments for iPXE script
-h This ;-)
"
while getopts "c:a:n:s:S:i:pI:b:B:k:h" OPTION
do
case "${OPTION}" in
c) compartment="${OPTARG}" ;;
a) availability_domain="${OPTARG}" ;;
n) name="${OPTARG}" ;;
s) shape="${OPTARG}" ;;
S) subnet_id="${OPTARG}" ;;
i) ignition="${OPTARG}" ;;
p) ipxe=1 ;;
I) image_id="${OPTARG}" ;;
b) baseurl="${OPTARG}" ;;
B) bucket_base="${OPTARG}" ;;
k) kargs="${OPTARG}" ;;
h) echo "${usage}"; exit 2 ;;
*) exit 2 ;;
esac
done
if [[ -z "${name}" ]]; then
echo "Instance name is required." >&2
exit 2
fi
launch_args=()
if [[ "${ipxe}" = 1 ]]; then
# Make scratch dir
tmpdir=$(mktemp -d bmcs-XXXXXX)
trap "rm -rf '${tmpdir}'" EXIT
if [[ -n "${ignition}" ]]; then
# Generate OEM image
mkdir -p "${tmpdir}/usr/share/oem"
cp "${ignition}" "${tmpdir}/usr/share/oem/ign.ign"
pushd "${tmpdir}" >/dev/null
find usr | cpio -o -H newc --quiet | gzip -c > oem.cpio.gz
popd >/dev/null
# Upload it. Don't delete it afterward, since the instance could
# reboot at any point and need the OEM image again.
oempath="${bucket_base}/$(mktemp -u XXXXXXX)"
gsutil -q cp "${tmpdir}/oem.cpio.gz" "gs://${oempath}"
ignition_initrd_args="initrd=ignition coreos.config.url=oem:///ign.ign"
ignition_initrd_cmd="initrd --name ignition http://${oempath}"
fi
# Create iPXE script
cat >"${tmpdir}/ipxe" <<EOF
#!ipxe
kernel ${baseurl}/coreos_production_pxe.vmlinuz initrd=coreos_production_pxe_image.cpio.gz coreos.first_boot=1 ${ignition_initrd_args} console=ttyS0,9600 ${kargs}
initrd ${baseurl}/coreos_production_pxe_image.cpio.gz
${ignition_initrd_cmd}
boot
EOF
launch_args+=("--ipxe-script-file" "${tmpdir}/ipxe")
fi
# Launch image
if [[ -n "${ignition}" ]]; then
launch_args+=("--user-data-file" "${ignition}")
fi
bmcs compute instance launch \
--availability-domain "${availability_domain}" \
--compartment-id "${compartment}" \
--image-id "${image_id}" \
--shape "${shape}" \
--display-name "${name}" \
--hostname-label "${name}" \
--subnet-id "${subnet_id}" \
${launch_args[@]}

75
oem/oracle/upload-image Executable file
View File

@ -0,0 +1,75 @@
#!/bin/bash
set -e -o pipefail
. common.sh
compartment=$(get_tenancy_id)
display_name=
path=
namespace=$(get_namespace_id)
bucket="image-upload"
# Parse args
usage="Usage: $0 [args] -n name -f file
Options:
-c COMPARTMENT Compartment ID (default: ${compartment})
-n DISPLAY-NAME Image display name
-f PATH Image file
-N NAMESPACE Object storage namespace (default: ${namespace})
-B BUCKET Bucket name (default: ${bucket})
-h This ;-)
"
while getopts "c:n:f:N:B:h" OPTION
do
case "${OPTION}" in
c) compartment="${OPTARG}" ;;
n) display_name="${OPTARG}" ;;
f) path="${OPTARG}" ;;
N) namespace="${OPTARG}" ;;
B) bucket="${OPTARG}" ;;
h) echo "${usage}"; exit 2 ;;
*) exit 2 ;;
esac
done
if [[ -z "${display_name}" ]]; then
echo "Display name is required." >&2
exit 2
fi
if [[ -z "${path}" ]]; then
echo "Image file is required." >&2
exit 2
fi
object=$(mktemp -u XXXXXXXXXXXXXXXX)
# Upload object
bmcs os object put \
--namespace "${namespace}" \
--bucket-name "${bucket}" \
--file "${path}" \
--name "${object}"
trap 'bmcs os object delete \
--namespace "${namespace}" \
--bucket-name "${bucket}" \
--name "${object}" \
--force' EXIT
# Initiate import
image_id=$(bmcs compute image import from-object \
--compartment-id "${compartment}" \
--display-name "${display_name}" \
--namespace "${namespace}" \
--bucket-name "${bucket}" \
--name "${object}" | jq -r .data.id)
# Wait for import
echo "Waiting for import..."
state=IMPORTING
while [[ "$state" = IMPORTING ]]; do
sleep 10
state=$(bmcs compute image get --image-id "${image_id}" | jq -r '.data["lifecycle-state"]')
done
echo "${state} ${image_id}"