-
Notifications
You must be signed in to change notification settings - Fork 9
/
machine.sh
executable file
·196 lines (163 loc) · 4.92 KB
/
machine.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/bin/bash
COMMAND=$1
NAME=$2
HYPERVISOR=$3
OSTYPE=ubuntu_20_04
PACKET_PLAN=${PACKET_PLAN:-baremetal_0}
PROJECT=${PACKET_PROJECT:-packer}
AZURE_PLAN=${AZURE_PLAN:-Standard_D2s_v3}
if [ -z "${COMMAND}" ] || [ "${COMMAND}" == "--help" ] ; then
echo "Usage:"
echo " $0 cleanup delete old machines"
echo " $0 create name type create a new machine with vmware|virtualbox"
echo " $0 delete name delete a machine"
echo " $0 ip name get IP address of a machine"
echo " $0 list list all machines"
echo " $0 provision name type provision the machine with vmware|virtualbox"
echo " $0 ssh name ssh into a machine"
echo " $0 start name start a machine"
echo " $0 stop name stop a machine"
exit 1
fi
TOKEN=${PACKET_APIKEY}
if [ -z "${TOKEN}" ]; then
TOKEN=$(pass packet_token)
fi
function create {
NAME=$1
PROJECTID=$2
HYPERVISOR=$3
if [ -z "${NAME}" ]; then
echo "Usage: $0 name"
exit 1
fi
# create project if it does not exist
if [ -z "${PROJECTID}" ]; then
PROJECTID=$(packet -k "${TOKEN}" \
admin create-project --name "${PROJECT}" | jq -r .id)
fi
for facility in ewr1 sjc1 dfw2 ams1 nrt1
do
echo "Creating baremetal machine in packet facility $facility"
# create machine
if packet -k "${TOKEN}" baremetal create-device \
--billing hourly \
--facility "${facility}" \
--os-type "${OSTYPE}" \
--plan "${PACKET_PLAN}" \
--project-id "${PROJECTID}" \
--hostname "${NAME}"; then
break
fi
done
provision "${NAME}" "${PROJECTID}" "${HYPERVISOR}"
}
function cmd {
NAME=$1
PROJECTID=$2
CMD=$3
if [ -z "${NAME}" ] || [ -z "${PROJECTID}" ] || [ -z "${CMD}" ]; then
echo "Usage: $0 name id command"
exit 1
fi
DEVICEID=$(packet -k "${TOKEN}" \
baremetal list-devices --project-id "${PROJECTID}" | jq -r ".[] | select(.hostname == \"${NAME}\") .id")
packet -k "${TOKEN}" \
baremetal "${CMD}" --device-id "${DEVICEID}"
}
function start {
echo "Starting $1"
cmd "$1" "$2" poweron-device
}
function stop {
echo "Stopping $1"
cmd "$1" "$2" poweroff-device
}
function delete {
echo "Deleting $1"
cmd "$1" "$2" delete-device
}
function cleanup {
machines=$(packet -k "${TOKEN}" baremetal list-devices --project-id "${PROJECTID}" | \
jq -r '.[] | .hostname')
for m in $machines
do
circle_build_num=${m#*e}
RESPONSE=$(curl \
--silent -S \
--fail \
"https://circleci.com/api/v1.1/project/github/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/${circle_build_num}")
STATE=$(echo "${RESPONSE}" | jq -r .lifecycle)
echo "Found machine $m, CircleCI build ${circle_build_num} is ${STATE}"
if [ "${STATE}" == "finished" ]; then
echo "Removing resources of finished CircleCI job $circle_build_num"
delete "$m" "$2"
fi
done
echo "Cleanup done."
}
function list {
packet -k "${TOKEN}" baremetal list-devices --project-id "${PROJECTID}" | \
jq -r '.[] | .hostname + " " + .state'
}
function ip {
packet -k "${TOKEN}" baremetal list-devices --project-id "${PROJECTID}" | \
jq -r ".[] | select(.hostname == \"${NAME}\") | .ip_addresses[] | select(.public == true) | select(.address_family == 4).address" | head -1
}
function provision {
echo "Provisioning $1"
IP=$(ip)
ssh-keygen -R "${IP}"
ssh-keyscan "${IP}" >>~/.ssh/known_hosts
/usr/bin/ssh "root@${IP}" < "scripts/provision-${HYPERVISOR}-builder.sh"
}
function ssh {
/usr/bin/ssh "root@$(ip)"
}
function azure_create {
NAME=$1
HYPERVISOR=$2
cd hyperv
terraform init -input=false
echo "Running Terraform to build VM ${NAME}"
terraform apply -input=false -auto-approve --var "name=${NAME}" --var "vm_size=${AZURE_PLAN}"
echo "Refreshing Terraform state"
terraform refresh -input=false | grep -vi password
IP=$(terraform output ip)
if [ -z "$IP" ]; then
echo "Waiting for IP"
sleep 60
IP=$(terraform output ip)
fi
echo "IP address of Azure VM $NAME: $IP"
echo "Wait until SSH is available"
maxConnectionAttempts=30
sleepSeconds=20
index=1
success=0
while (( index <= maxConnectionAttempts ))
do
/usr/bin/ssh -o StrictHostKeyChecking=no "packer@$IP" ver
case $? in
(0) echo "${index}> Success"; ((success+=1));;
(*) echo "${index} of ${maxConnectionAttempts}> SSH server not ready yet, waiting ${sleepSeconds} seconds..."; success=0 ;;
esac
if [ $success -eq 2 ]; then
break
fi
sleep $sleepSeconds
((index+=1))
done
set -e
ssh-keygen -R "${IP}"
ssh-keyscan "${IP}" >>~/.ssh/known_hosts
}
if [ "${HYPERVISOR}" == "hyperv" ]; then
azure_create "${NAME}" "${HYPERVISOR}"
elif [ "${HYPERVISOR}" == "azure" ]; then
azure_create "${NAME}" "${HYPERVISOR}"
else
PROJECTID=$(packet -k "${TOKEN}" \
admin list-projects | jq -r ".[] | select(.name == \"${PROJECT}\") .id")
"${COMMAND}" "${NAME}" "${PROJECTID}" "${HYPERVISOR}"
fi