-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcommon.sh
More file actions
executable file
·252 lines (214 loc) · 6.92 KB
/
common.sh
File metadata and controls
executable file
·252 lines (214 loc) · 6.92 KB
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
#!/usr/bin/env bash
################################################################################
################################################################################
# Name: common.sh
# Usage: n/a
# Description: Common functions useful to the other scripts
# Created: n/a
# Last Modified: n/a
################################################################################
################################################################################
# stop the script when an error occurs
# and cause a pipeline (for example, curl -s https://sipb.mit.edu/ | grep foo)
# to produce a failure return code if any command errors.
# Normally, pipelines only return a failure if the last command errors
set -eo pipefail
export DEBIAN_FRONTEND=noninteractive
LOG_DIRECTORY='logs'
LOG_FILE="${LOG_DIRECTORY}/"$(date +%Y-%m-%d).log
# app versions and other useful shortcuts
SDKMAN_URL="https://get.sdkman.io"
JAVA_VERSION_ARCH="jdk8"
JAVA_VERSION_DEBIAN="openjdk-11-jdk"
JAVA_VERSION_FEDORA="java-11-openjdk"
RBENV_REPO="git://github.com/sstephenson/ruby-build.git"
RUBY_VERSION="2.6.1"
RAILS_VERSION="5.2.2"
# Usage: _outputMessage <message>
#
# Outputs <message> to the terminal
# And also logs to the current LOG_FILE value
_outputMessage() {
if [[ "$#" -ne 1 ]]; then
_errorExit "Function _outputMessage expected 1 (one) parameter but got $#: '$*'. Usage: _outputMessage <message>"
fi
local fmt="$1"
shift
date=$(/bin/date "+%F %T")
outputMessage="$fmt\n" "$@"
_logMessage "$outputMessage"
printf "$date: $outputMessage"
}
# Usage _logMessage <message>
#
# Append string to the end of the timestamped log file
_logMessage() {
if [[ "$#" -ne 1 ]]; then
_errorExit "Function _logMessage expected 1 (one) parameter but got $#: '$*'. Usage: _logMessage <message>"
fi
if [[ ! -d "$LOG_DIRECTORY" ]]; then
mkdir ${LOG_DIRECTORY}
fi
if [[ ! -e "$LOG_FILE" ]]; then
touch "${LOG_FILE}"
fi
date=$(/bin/date "+%F %T")
printf "$date: $1" >>$LOG_FILE 2>&1
}
# Usage: _scriptCompletedMessage
#
# Prints some finishing statistics
# Currently shows how long a script took to run based on when it started
_scriptCompletedMessage() {
if [[ "$#" -ne 1 ]]; then
_errorExit "Function _scriptCompletedMessage expected 1 (one) parameter but got $#: '$*'. Usage: _scriptCompletedMessage <start_time_in_sec>"
fi
local start_sec=$1
local end_sec=$(/bin/date +%s.%N)
# shellcheck disable=SC2154
elapsed_seconds=$(echo "$end_sec" "$start_sec" | awk '{ print $1 - $2 }')
_outputMessage "Finished execution of $(basename "$0") in $elapsed_seconds seconds\n"
}
# Usage: _errorExit <message>
#
# Writes <message> to screen and logfile as a "fatal"
# And immediately exits the currently running script
_errorExit() {
if [[ "$#" -ne 1 ]]; then
_outputMessage "[FATAL] Function _errorExit expected 1 (one) parameter but got $#: '$*'. Usage: _errorExit <message>"
exit 1
fi
local date=$(/bin/date "+%F %T")
local message=$1
printf "$date: [FATAL] $message\n" "$@" | tee -a ${LOG_FILE}
exit 1
}
# Usage: _getLinuxVersion
#
# Determines linux-flavor running on the machine in use
_getLinuxVersion() {
# Fedora stores the distro id as ID under /etc/os-release
# Ubuntu and Arch store the distro id as ID_LIKE under /etc/os-release
#
# TODO: find how to make this into an elegant one liner
# $(cat /etc/*-release | grep -we "ID" -we "ID_LIKE" | awk -F '=' '{print $2}')
if [[ $(grep -r "ID_LIKE" /etc/os-release) ]]; then
dist=$(grep -w "ID_LIKE" /etc/os-release | awk -F '=' '{print $2}')
else
dist=$(grep -w "ID" /etc/os-release | awk -F '=' '{print $2}')
fi
echo "$dist"
}
# Usage _ask <question> <response> eg _ask "Install package?" "N"
# https://github.com/minamarkham/formation/blob/master/twirl#L445
#
# Displays a yes/no prompt, and only allows input of Y or N
_ask() {
if [[ "$#" -ne 2 ]]; then
_errorExit "Function _ask expected 2 (two) parameters but got $#: '$*'. Usage: _ask <question> <Y/N>"
fi
local prompt default reply
shopt -s nocasematch
if [[ "${2}" =~ "y" ]]; then
prompt="Y/n"
default=Y
elif [[ "${2}" =~ "n" ]]; then
prompt="y/N"
default=N
else
prompt="y/n"
default=
fi
shopt -u nocasematch
if [[ ${AUTO_ANSWER} ]]; then
_logMessage " [?] $1 [$prompt]: $default\n"
case "${2:-}" in
Y* | y*) return 0 ;;
N* | n*) return 1 ;;
esac
else
while true; do
# Ask the question (not using "read -p" as it uses stderr not stdout)
echo -n " [?] $1 [$prompt] "
# Read the answer (use /dev/tty in case stdin is redirected from somewhere else)
read reply </dev/tty
# Default?
if [[ -z "$reply" ]]; then
reply=$default
fi
_logMessage " [?] $1 [$prompt]: $reply\n"
# Check if the reply is valid
case "$reply" in
Y* | y*) return 0 ;;
N* | n*) return 1 ;;
esac
done
fi
}
# Usage _hasSudo
#
# Ensure user has root access and also that the script is not running as root
# Halts all activity if running as root
_hasSudo() {
isRoot=$(id -u)
if [[ ! ${CIRCLECI} && ${isRoot} = 0 ]]; then
_errorExit "Please run scripts as a normal user and not as root"
fi
if ! sudo -n true 2>/dev/null; then
# prompt for password and elevate privilege
printf "\nPlease provide your root password to allow this script to work as intended\n"
sudo -v
fi
}
# Usage _installPackage <package-name>
#
# Based on the OS in use, install the specified package
_installPackage() {
if [[ "$#" -ne 1 ]]; then
_errorExit "Function _installPackage expected 1 (one) parameter but got $#: '$*'. Usage: _installPackage '<package-name>'"
fi
_isOnline
_hasSudo
_outputMessage "Trying to install $1"
case $(_getLinuxVersion) in
arch)
yay -S --noconfirm --needed --overwrite '*' "${1}"
;;
debian)
sudo apt install -y "${1}"
;;
fedora)
sudo dnf install -y "${1}"
;;
*)
_errorExit "Could not determine OS/distro in use to install $1. Parser found $(_getLinuxVersion)"
;;
esac
_outputMessage "Successfully installed $1"
}
# Usage _isOnline
#
# Ensure Internet connection, exits if there's no connection
_isOnline() {
# circleci will not run ping, and will fail with a socket error
# so if circleci, assume we have an internet connection
if [[ ! ${CIRCLECI} ]]; then
isOnline=$(ping -q -w1 -c1 google.com &>/dev/null && echo online || echo offline)
if [[ ${isOnline} == "offline" ]]; then
_errorExit "Cannot install packages when offline"
else
_outputMessage "Internet connection verified successfully"
fi
else
_outputMessage "Skipping internet connection check"
fi
}
# Display header message, mostly used for a nice separator between "execution phases"
#
# $1 - message
_writeHeader() {
local h="$@"
echo "---------------------------------------------------------------"
echo " ${h}"
echo "---------------------------------------------------------------"
}