Skip to content

Commit 1a40907

Browse files
committed
feat: Add workflow for collecting instance uptimes
1 parent d4ff10c commit 1a40907

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Collect Instance Uptime
2+
on:
3+
# schedule:
4+
# # Run every 5 mins
5+
# - cron: "* * * * *"
6+
workflow_dispatch:
7+
8+
jobs:
9+
collect-instance-uptime:
10+
runs-on: self-hosted
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Collect Instance Uptime
15+
run: |
16+
export OS_CLOUD=BIO180006_IU # Select openstack auth settings defined in ".config/openstack/clouds.yaml"
17+
18+
source ~/venv/bin/activate
19+
20+
instance_prefix=${PREFIX:+${PREFIX}_}
21+
instance_basename="${instance_prefix}instance"
22+
23+
JSON_FILE=uptime.json
24+
JSON_FILE_TMP=uptime.json.tmp
25+
26+
if [[ ! -f $JSON_FILE ]]; then
27+
jq --null-input \
28+
--arg allocation_id "$OS_CLOUD" \
29+
'{"allocations": [{"id": $allocation_id, "instances": []}]}' > $JSON_FILE
30+
fi
31+
32+
openstack server list --name "^${instance_basename}-\d+" -f json | \
33+
jq -r '.[] | [.Name, .Status, ."OS-EXT-STS:task_state"] | @tsv' | \
34+
while IFS=$'\t' read -r instance_name status task_state; do
35+
echo "instance_name [$instance_name] status [$status] task_state [$task_state]"
36+
if [[ "$status" != "ACTIVE" ]]; then
37+
# Skip because instance is not active
38+
continue
39+
fi
40+
if [[ "$task_state" != "" ]]; then
41+
# Skip because instance status is being updated
42+
continue
43+
fi
44+
# Extract issue number
45+
issue_number=${instance_name##*-}
46+
echo "issue_number [$issue_number]"
47+
# Get instance IP
48+
instance_ip=$(
49+
openstack server show $instance_name -c addresses -f json | \
50+
jq -r '.addresses.auto_allocated_network[1]'
51+
)
52+
echo "instance_ip [$instance_ip]"
53+
if [[ "$instance_ip" == "null" ]]; then
54+
echo "::warning ::Failed to retrieve $instance_name IP"
55+
continue
56+
fi
57+
# Retrieve uptime
58+
uptime=$(ssh \
59+
-o StrictHostKeyChecking=no \
60+
-o UserKnownHostsFile=/dev/null \
61+
-o LogLevel=ERROR \
62+
exouser@$instance_ip \
63+
'cat /proc/uptime | awk "{print \$1}"')
64+
65+
# Retrieve startup time in yyyy-mm-dd HH:MM:SS format
66+
startup_time=$(ssh \
67+
-o StrictHostKeyChecking=no \
68+
-o UserKnownHostsFile=/dev/null \
69+
-o LogLevel=ERROR \
70+
exouser@$instance_ip \
71+
'uptime -s')
72+
73+
# Check if there is an entry for instance_name
74+
has_instance=(cat $JSON_FILE | jq \
75+
--arg allocation_id "$OS_CLOUD" \
76+
--arg instance_name "$instance_name" \
77+
--arg startup_time "$startup_time" \
78+
'any(.allocations[] | select(.id == $allocation_id) | .instances[]; .name == $instance_name)')
79+
if [[ "$has_instance" == "false" ]]; then
80+
# Add entry
81+
cat $JSON_FILE | jq \
82+
--arg allocation_id "$OS_CLOUD" \
83+
--arg instance_name "$instance_name" \
84+
'(.allocations[] | select(.id == $allocation_id) | .instances)
85+
+= [{"name": $instance_name, "uptimes": {}}]' > $JSON_FILE_TMP \
86+
&& mv $JSON_FILE_TMP $JSON_FILE
87+
fi
88+
89+
# Check if there is an entry for startup_time
90+
has_startup_time=(cat $JSON_FILE | jq \
91+
--arg allocation_id "$OS_CLOUD" \
92+
--arg instance_name "$instance_name" \
93+
--arg startup_time "$startup_time" \
94+
'(.allocations[] | select(.id == $allocation_id) | .instances[] | select(.name == $instance_name) | .uptimes | has($startup_time))')
95+
96+
if [[ "$has_startup_time" == "false"]]; then
97+
# Add entry
98+
cat $JSON_FILE | jq \
99+
--arg allocation_id "$OS_CLOUD" \
100+
--arg instance_name "$instance_name" \
101+
--arg startup_time "$startup_time" \
102+
--arg uptime "$uptime" \
103+
'(.allocations[] | select(.id == $allocation_id) | .instances[] | select(.name == $instance_name) | .uptimes)
104+
+= {($startup_time): $uptime|tonumber}' > $JSON_FILE_TMP \
105+
&& mv $JSON_FILE_TMP $JSON_FILE
106+
else
107+
# Update entry
108+
cat $JSON_FILE | jq \
109+
--arg allocation_id "$OS_CLOUD" \
110+
--arg instance_name "$instance_name" \
111+
--arg startup_time "$startup_time" \
112+
--arg uptime "$uptime" \
113+
'(.allocations[] | select(.id == $allocation_id) | .instances[] | select(.name == $instance_name) | .uptimes[$startup_time])
114+
= ($uptime|tonumber)' > $JSON_FILE_TMP \
115+
&& mv $JSON_FILE_TMP $JSON_FILE
116+
fi
117+
done
118+
119+
echo "--------"
120+
cat $JSON_FILE
121+
echo "--------"
122+
env:
123+
PREFIX: ${{ vars.INSTANCE_NAME_PREFIX }}

0 commit comments

Comments
 (0)