33set -o errexit
44set -o pipefail
55
6- # Copyright (c) 2023-2024 Deephaven Data Labs and Patent Pending
6+ # Copyright (c) 2023-2026 Deephaven Data Labs and Patent Pending
77
88# Provides what is needed to set up an adhoc benchmark run, including bare metal and labels
99# ex. adhoc.sh make-labels "where" "0.36.0" "user123:branch-name-123"
10- # ex. adhoc.sh metal-deploy api-key project-id c3.small.x86 server-name "2 days"
11- # ex. adhoc.sh metal-delete api-key device-id service-name
10+ # ex. adhoc.sh scale-nums 10 5
11+ # ex. adhoc.sh deploy-metal api-key project-id s2.c2.small server-name
12+ # ex. adhoc.sh delete-metal api-key device-id service-name
13+ # ex. adhoc.sh purge-metal api-key project-id
1214
1315if [[ $# < 2 ]]; then
1416 echo " $0 : Missing action or its arguments"
@@ -21,13 +23,6 @@ OUTPUT_NAME=adhoc-${ACTION}.out
2123
2224rm -f ${OUTPUT_NAME} ; touch ${OUTPUT_NAME}
2325
24- # Get metal device info including ip address
25- getDeviceInfo () {
26- curl --no-progress-meter --max-time 10 -X GET -H " X-Auth-Token: $1 " \
27- " https://api.equinix.com/metal/v1/devices/$2 ?include=ip_addresses,state&exclude=root_password,ssh_keys" \
28- | jq | tee get-device-response.json | jq -r " $3 "
29- }
30-
3126# Get the label part of an image/branch name
3227# ex. edge@sha256:15ab331629805076cdf5ed6666186c6b578298ab493a980779338d153214640e
3328# ex. user123:1111-my-pull-request
@@ -48,69 +43,66 @@ if [[ ${ACTION} == "make-labels" ]]; then
4843 IMAGE1=$3
4944 IMAGE2=$4
5045 echo " Making Labels: ${PREFIX} "
51-
46+
5247 LABEL1=$( getSetLabel ${PREFIX} ${IMAGE1} )
5348 LABEL2=$( getSetLabel ${PREFIX} ${IMAGE2} )
54-
49+
5550 echo " PREFIX=${PREFIX} " | tee -a ${OUTPUT_NAME}
5651 echo " SET_LABEL_1=${LABEL1} " | tee -a ${OUTPUT_NAME}
5752 echo " SET_LABEL_2=${LABEL2} " | tee -a ${OUTPUT_NAME}
5853fi
5954
60- # Format some number used for scaling the tests
55+ # Format some numbers used for scaling the tests
6156if [[ ${ACTION} == " scale-nums" ]]; then
6257 INPUT_ROW_COUNT=$2
6358 INPUT_ITERATIONS=$3
6459 echo " Scaling Numbers"
65-
60+
6661 TEST_ROW_COUNT=$(( ${INPUT_ROW_COUNT} * 1000000 ))
6762 TEST_ITERATIONS=${INPUT_ITERATIONS}
6863 if [ $(( ${INPUT_ITERATIONS} % 2 )) == 0 ]; then
6964 TEST_ITERATIONS=$(( ${INPUT_ITERATIONS} + 1 ))
7065 fi
71-
66+
7267 echo " INPUT_ROW_COUNT=${INPUT_ROW_COUNT} " | tee -a ${OUTPUT_NAME}
7368 echo " INPUT_ITERATIONS=${INPUT_ITERATIONS} " | tee -a ${OUTPUT_NAME}
7469 echo " TEST_ROW_COUNT=${TEST_ROW_COUNT} " | tee -a ${OUTPUT_NAME}
7570 echo " TEST_ITERATIONS=${TEST_ITERATIONS} " | tee -a ${OUTPUT_NAME}
7671fi
7772
78- # Deploy a bare metal server using the Equinix ReST API
73+ # Deploy a bare metal server using tofu
7974if [[ ${ACTION} == " deploy-metal" ]]; then
8075 API_KEY=$2
8176 PROJECT_ID=$3
8277 PLAN=$4
8378 ACTOR=$( echo " adhoc-$5 -" $( ${SCRIPT_DIR} /base.sh $( date +%s%03N) 36) | tr ' [:upper:]' ' [:lower:]' )
84- EXPIRE_WHEN=$6
8579 echo " Deploying Server: ${ACTOR} "
86-
8780 BEGIN_SECS=$( date +%s)
88- DEVICE_ID=$( curl --fail-with-body -X POST \
89- -H " Content-Type: application/json" -H " X-Auth-Token: ${API_KEY} " \
90- " https://api.equinix.com/metal/v1/projects/${PROJECT_ID} /devices?exclude=plan,ssh_keys,provisioning_events,network_ports,operating_system" \
91- -d ' {
92- "metro": "sv",
93- "plan": "' ${PLAN} ' ",
94- "operating_system": "ubuntu_22_04",
95- "hostname": "' ${ACTOR} ' ",
96- "termination_time": "' $( date --iso-8601=seconds -d " +${EXPIRE_WHEN} " ) ' "
97- }' | jq | tee create-device-response.json | jq -r ' .id' )
98-
99- IP_ADDRESS=" null"
100- for i in $( seq 100) ; do
101- echo -n " $i ) Device Status: "
102- STATE=$( getDeviceInfo ${API_KEY} ${DEVICE_ID} " .state" )
103- echo " ${STATE} "
104- if [[ " ${STATE} " == " active" ]]; then break ; fi
105- sleep 6
81+
82+ export TF_VAR_client_id=" ${PROJECT_ID} "
83+ export TF_VAR_client_secret=" ${API_KEY} "
84+ export TF_VAR_hostname=" ${ACTOR} "
85+ export TF_VAR_plan=" ${PLAN} "
86+
87+ pushd ${SCRIPT_DIR} /../resources
88+ tofu init -input=false
89+ tofu apply -auto-approve -input=false
90+ IP_ADDRESS=$( tofu output -raw public_ip)
91+ DEVICE_ID=$( tofu output -raw server_id)
92+ popd
93+
94+ STATUS=0
95+ for i in {1..30}; do
96+ if ssh -o StrictHostKeyChecking=no benchmark@" ${IP_ADDRESS} " " echo ok" 2> /dev/null; then
97+ STATUS=1
98+ break
99+ fi
100+ sleep 10
106101 done
107-
102+
108103 DURATION=$(( $(date +% s) - ${BEGIN_SECS} ))
109-
110- IP_ADDRESS=$( getDeviceInfo ${API_KEY} ${DEVICE_ID} " .ip_addresses[0].address" )
111- STATE=$( getDeviceInfo ${API_KEY} ${DEVICE_ID} " .state" )
112- if [[ " ${IP_ADDRESS} " == " null" ]] || [[ " ${STATE} " != " active" ]]; then
113- echo " Failed to provision device after ${DURATION} seconds"
104+ if [[ ${STATUS} -eq 0 ]]; then
105+ echo " Failed to provision device ${ACTOR} after ${DURATION} seconds"
114106 exit 1
115107 fi
116108
@@ -119,23 +111,57 @@ if [[ ${ACTION} == "deploy-metal" ]]; then
119111 echo " DEVICE_NAME=${ACTOR} " | tee -a ${OUTPUT_NAME}
120112 echo " DEVICE_ID=${DEVICE_ID} " | tee -a ${OUTPUT_NAME}
121113 echo " DEVICE_ADDR=${IP_ADDRESS} " | tee -a ${OUTPUT_NAME}
122- echo " DEVICE_EXPIRE=${EXPIRE_WHEN} " | tee -a ${OUTPUT_NAME}
123114fi
124115
125- # Delete a bare metal server using the Equlinix ReST API
116+ # Delete a bare metal server. Expects that tofu state exists from a previous tofu create
126117if [[ ${ACTION} == " delete-metal" ]]; then
127118 API_KEY=$2
128119 DEVICE_ID=$3
129120 DEVICE_NAME=$4
130121
131- curl --no-progress-meter --max-time 10 --fail-with-body -X DELETE -H " X-Auth-Token: ${API_KEY} " \
132- " https://api.equinix.com/metal/v1/devices/ ${DEVICE_ID} " \
133- | jq | tee delete-device-response.json
122+ pushd ${SCRIPT_DIR} /../resources
123+ tofu destroy -auto-approve
124+ popd
134125
135126 echo " ACTION=${ACTION} " | tee -a ${OUTPUT_NAME}
136127 echo " DEVICE_NAME=${DEVICE_NAME} " | tee -a ${OUTPUT_NAME}
137128 echo " DEVICE_ID=${DEVICE_ID} " | tee -a ${OUTPUT_NAME}
138129fi
139130
131+ # Purge all ephemeral metal that's past its expiration date
132+ if [[ ${ACTION} == " purge-metal" ]]; then
133+ API_KEY=$2
134+ PROJECT_ID=$3
135+ EXPIRATION_HOURS=24
136+
137+ echo " Starting Ephemeral Server Cleanup"
138+ echo " Max Hours to Expiration: ${EXPIRATION_HOURS} "
139+ echo " Requesting OAuth2 Token"
140+ TOKEN=$( curl -s -X POST -d " grant_type=client_credentials" -d " client_id=${PROJECT_ID} " -d " client_secret=${API_KEY} " \
141+ https://auth.phoenixnap.com/auth/realms/BMC/protocol/openid-connect/token | jq -r ' .access_token' )
142+
143+ if [[ -z " $TOKEN " || " $TOKEN " == " null" ]]; then
144+ echo " Failed to obtain OAuth2 Token"
145+ exit 1
146+ fi
147+ echo " OAuth2 Token Acquired"
148+
149+ CUTOFF=$( date -u -d " $TTL_HOURS hours ago" +" %Y-%m-%dT%H:%M:%SZ" )
150+ echo " Fetching Ephemeral Servers"
151+ SERVERS=$( curl -s -H " Authorization: Bearer $TOKEN " " https://api.phoenixnap.com/bmc/v1/servers?tag=ephemeral" )
152+ COUNT=$( echo " $servers " | jq ' length' )
153+ echo " Found ${COUNT} Ephemeral Servers."
154+
155+ echo " ${SERVERS} " | jq -c ' .[]' | while read server; do
156+ id=$( echo " $server " | jq -r ' .id' )
157+ hostname=$( echo " $server " | jq -r ' .hostname' )
158+ created=$( echo " $server " | jq -r ' .creationDate' )
159+ if [[ " $created " < " ${CUTOFF} " ]]; then
160+ echo " Deleting Server: $hostname ($id )"
161+ curl -s -X DELETE -H " Authorization: Bearer $TOKEN " " https://api.phoenixnap.com/bmc/v1/servers/$id " > /dev/null
162+ fi
163+ done
140164
165+ echo " ACTION=${ACTION} " | tee -a ${OUTPUT_NAME}
166+ fi
141167
0 commit comments