forked from nbeede/BoomBox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.sh
executable file
·297 lines (265 loc) · 9.5 KB
/
build.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
#! /bin/bash
# Run this script on a fresh clone of BoomBox. It will fail to run if boxes
# have already been created or any of the steps from the README have already
# been executed. Only MacOS and Linux are supported. Use build.ps1 for Windows.
print_usage() {
echo "Usage: ./build.sh virtualbox [--vagrant-only | --packer-only]"
exit 0
}
parse_cli_arguments() {
# If no argument was supplied, list available providers
if [ "$#" -eq 0 ]; then
PROVIDER=$(list_providers)
fi
# If more than two arguments were supplied, print usage message
if [ "$#" -gt 2 ]; then
print_usage
exit 1
fi
if [ "$#" -ge 1 ]; then
# If the user speicifies the provider as an argument, set the variable.
case "$1" in
virtualbox)
PROVIDER="$1"
PACKER_PROVIDER="$1"
;;
*)
echo "\"$1\" is not a valid provider. Listing available providers:"
PROVIDER=$(list_providers)
;;
esac
fi
if [ $# -eq 2 ]; then
case "$2" in
--packer-only)
PACKER_ONLY=1
;;
--vagrant-only)
VAGRANT_ONLY=1
;;
*)
echo -e "\"$2\" is not recognized as an option. Available options are:\\n--packer-only\\n--vagrant-only"
exit 1
;;
esac
fi
}
list_providers() {
VBOX_PRESENT=0
if [ "$(uname)" == "Darwin" ]; then
# Detect Providers on OSX
# Place holding for future Vagrant providers
VBOX_PRESENT=$(check_virtualbox_installed)
else
VBOX_PRESENT=$(check_virtualbox_installed)
fi
(echo >&2 "Available Providers:")
if [ "$VBOX_PRESENT" == "1" ]; then
(echo >&2 "virtualbox")
fi
(echo >&2 -e "\\nWhich provider would you like to use?")
read -r PROVIDER
# Sanity check
if [[ "$PROVIDER" != "virtualbox" ]]; then
(echo >&2 "Please choose a valid provider. \"$PROVIDER\" is not a valid option.")
exit 1
fi
echo "$PROVIDER"
}
check_virtualbox_installed() {
if which VBoxManage >/dev/null; then
echo "1"
else
echo "0"
fi
}
check_packer_path() {
# Check for existence of Packer in PATH
if ! which packer >/dev/null; then
(echo >&2 "Packer was not found in your PATH.")
(echo >&2 "Please correct this before continuing. Quitting.")
(echo >&2 "You can download it here: https://www.packer.io/downloads.html")
(echo >&2 "Hint: sudo cp ./packer /usr/local/bin/packer; sudo chmod +x /usr/local/bin/packer")
exit 1
fi
}
check_vagrant_path() {
# Check for existence of Vagrant in PATH
if ! which vagrant >/dev/null; then
(echo >&2 "Vagrant was not found in your PATH.")
(echo >&2 "Please correct this before continuing. Quitting.")
(echo >&2 "You can download it here: https://www.vagrantup.com/downloads.html")
(echo >&2 "Hint: sudo cp ./vagrant /usr/local/bin/vagrant; sudo chmod +x /usr/local/bin/vagrant")
exit 1
fi
}
check_vagrant_instances_exist() {
# Check to see if any Vagrant instances exist already
cd "$DL_DIR"/Vagrant || exit 1
# Vagrant status has the potential to return a non-zero error code, so we work around it with "|| true"
VAGRANT_BUILT=$(vagrant status | grep -c 'not created') || true
if [ "$VAGRANT_BUILT" -ne 2 ]; then
(echo >&2 "You appear to have already created at least one Vagrant instance of BoomBox. This script does not support pre-created instances. Please either destroy the existing instances or follow the build steps in the README to continue.")
exit 1
fi
}
check_vagrant_reload_plugin() {
# Ensure the vagrant-reload plugin is installed
VAGRANT_RELOAD_PLUGIN_INSTALLED=$(vagrant plugin list | grep -c 'vagrant-reload')
if [ "$VAGRANT_RELOAD_PLUGIN_INSTALLED" != "1" ]; then
(echo >&2 "The vagrant-reload plugin is required and not currently installed. This script will attempt to install it now.")
if ! $(which vagrant) plugin install "vagrant-reload"; then
(echo >&2 "Unable to install the vagrant-reload plugin. Please try to do so manually and re-run this script.")
exit 1
fi
fi
}
check_boxes_built() {
BOXES_BUILT=$(find "$DL_DIR"/Boxes -name "*.box" | wc -l)
if [ "$BOXES_BUILT" -gt 0 ]; then
if [ "$VAGRANT_ONLY" -eq 1 ]; then
(echo >&2 "WARNING: You seem to have at least one .box file present in $DL_DIR/Boxes already. If you would like fresh boxes, please remove all files from the Boxes directory and re-run this script.")
else
(echo >&2 "You seem to have at least one .box file in $DL_DIR/Boxes. This script does not support pre-built boxes. Please either delete the existing boxes or follow the build steps in the README to continue.")
exit 1
fi
fi
}
check_disk_free_space() {
# Check available disk space. Recommend 40GB free, warn if less.
FREE_DISK_SPACE=$(df -m "$HOME" | tr -s ' ' | grep '/' | cut -d ' ' -f 4)
if [ "$FREE_DISK_SPACE" -lt 40000 ]; then
(echo >&2 -e "Warning: You appear to have less than 40GB of HDD space free on your primary partition. If you are using a separate partition, you may ignore this warning.\n")
(df >&2 -m "$HOME")
(echo >&2 "")
fi
}
check_curl() {
# Check to see if curl is in PATH - needed for post-install checks
if ! which curl >/dev/null; then
(echo >&2 "Please install curl and make sure it is in your PATH.")
exit 1
fi
}
prereq_checks() {
# If it's not a Vagrant-only build, then run Packer-related checks
if [ "$VAGRANT_ONLY" -eq 0 ]; then
check_packer_path
fi
# If it's not a Packer-only build, then run Vagrant-related checks
if [ "$PACKER_ONLY" -eq 0 ]; then
check_vagrant_path
check_vagrant_instances_exist
check_vagrant_reload_plugin
fi
check_boxes_built
check_disk_free_space
check_curl
}
# Builds a box using Packer
packer_build_box() {
# Export the box in $DL_DIR default is /tmp
export TMP_DIR=$DL_DIR
BOX="$1"
cd "$DL_DIR/Packer" || exit 1
(echo >&2 "Using Packer to build the $BOX Box. This can take 90-180 minutes depending on bandwidth and hardware.")
PACKER_LOG=1 PACKER_LOG_PATH="$DL_DIR/Packer/packer_build.log"
$(which packer) build --only="virtualbox-iso" "$BOX".json >&2
echo "$?"
}
move_boxes() {
mv "$DL_DIR"/Packer/*.box "$DL_DIR"/Boxes
if [ ! -f "$DL_DIR"/Boxes/sandbox_virtualbox.box ]; then
(echo >&2 "Sandbox Box is missing from the Boxes directory. Quitting.")
exit 1
fi
}
build_vagrant_hosts() {
HOSTS=("sandbox" "cuckoo")
# load backwards for testing to not to build win image
#HOSTS=("cuckoo" "sandbox")
# Vagrant up each box and attempt to reload one time if it fails
for HOST in "${HOSTS[@]}"; do
RET=$(vagrant_up_host "$HOST")
if [ "$RET" -eq 0 ]; then
(echo >&2 "Good news! $HOST was build successfully!")
fi
# Attempt to recover if the initial "vagrant up" fails
if [ "$RET" -ne 0 ]; then
(echo >&2 "Something went wrong while attempting to build the $HOST box.")
(echo >&2 "Attempting to reload and reprovision the host...")
RETRY_STATUS=$(vagrant_reload_host "$HOST")
if [ "$RETRY_STATUS" -eq 0 ]; then
(echo >&2 "Good news! $HOST was built successfully after a reload. Exiting.")
else
(echo >&2 "Failed to bring up $HOST after a reload. Exiting.")
exit 1
fi
fi
done
}
vagrant_up_host() {
HOST="$1"
(echo >&2 "Attempting to bring up the $HOST host using Vagrant")
cd "$DL_DIR"/Vagrant || exit 1
$(which vagrant) up "$HOST" --provider=virtualbox &> "$DL_DIR/Vagrant/vagrant_up_$HOST.log"
echo "$?"
}
vagrant_reload_host() {
HOST="$1"
cd "$DL_DIR"/Vagrant || exit 1
# Attempt to reload the host if the vagrant up command didn't exit cleanly
$(which vagrant) reload "$HOST" --provision >> "$DL_DIR/Vagrant/vagrant_up_$HOST.log" 2>&1
echo "$?"
}
create_snapshot() {
# Poweroff and remove nat nic first
(echo >&2 "Powering off sandbox to remove NAT network adapter...")
$(which vboxmanage) controlvm sandbox poweroff &> "$DL_DIR/Vagrant/sandbox_snapshot.log"
sleep 5s
$(which vboxmanage) modifyvm sandbox --nic1 null >> "$DL_DIR/Vagrant/sandbox_snapshot.log"
sleep 5s
(echo >&2 "Starting sandbox and taking a base snapshot...")
$(which vboxmanage) startvm sandbox >> "$DL_DIR/Vagrant/sandbox_snapshot.log"
sleep 5s
# Take a snapshot of the sandbox once the agent is running and nat nic is removed.
$(which vboxmanage) snapshot "sandbox" take "base" --pause >> "$DL_DIR/Vagrant/sandbox_snapshot.log"
sleep 5s
(echo >&2 "Successfully completed sandbox snapshot!")
}
post_build_checks() {
# A series of checks to ensure important services are responsive after the build completes.
# Cuckoo Server
CUCKOO_CHECK=$(curl -ks -m 2 http://192.168.30.100:8080 | grep -c 'Cuckoo Sandbox' || echo "")
# Sandbox Agent
#AGENT_CHECK=$()
if [ "$CUCKOO_CHECK" -lt 1 ]; then
(echo >&2 "Warning: Cuckoo Web Server failed post-build tests and may not be functioning correctly.")
fi
}
main() {
# Get location of build.sh
# https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within
DL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKER_ONLY=0
VAGRANT_ONLY=0
parse_cli_arguments "$@"
prereq_checks
# Build Packer boxes if this isn't a Vagrant-only build
if [ "$VAGRANT_ONLY" -eq 0 ]; then
RET=$(packer_build_box "sandbox")
# The only time we will need to move boxes is if we're doing a full build
if [ "$PACKER_ONLY" -eq 0 ]; then
move_boxes
fi
fi
# Build and Test Vagrant hosts if this isn't a Packer-only build
if [ "$PACKER_ONLY" -eq 0 ]; then
build_vagrant_hosts
create_snapshot
post_build_checks
fi
(echo >&2 "Everything has completed! Cuckoo should now be available at http://192.168.30.100:8080")
}
main "$@"
exit 0