forked from jfrog/artifactory-docker-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
art-compose
executable file
·419 lines (359 loc) · 12.1 KB
/
art-compose
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
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
#!/bin/bash
######################################################
#
# This script is for starting up Artifactory with docker-compose.
# The file will create needed directories for data persistence
# and start Artifactory with PostgreSQL as DB and Nginx.
#
######################################################
SCRIPT_NAME=$(basename $0)
DEFAULT_ROOT_DATA_DIR=/data
LINUX_ROOT_DATA_DIR=${DEFAULT_ROOT_DATA_DIR}
MAC_DEFAULT_ROOT_DATA_DIR=~/.jfrog/artifactory
DB_DRIVER=postgresql-9.4.1212.jar
DB_DRIVER_URL=https://jdbc.postgresql.org/download/${DB_DRIVER}
ARTIFACTORY_VERSION=5.1.3
ART_COMPOSE_YML=https://jfrog.bintray.com/run/artifactory-pro/${ARTIFACTORY_VERSION}/compose/artifactory-pro.yml
COMPOSE_FILE=artifactory-pro.yml
DB_PASSWORD_FILE=.dbpassword
FRESH_YML=false
DATA_REMOVED=false
errorExit () {
echo; echo "ERROR: $1"; echo
exit 1
}
usage () {
cat << END_USAGE
$SCRIPT_NAME - script for starting and controlling an Artifactory Pro instance with Docker compose
Usage: ./$SCRIPT_NAME <options>
Supported options
-a : Action to run. start, stop, restart, status, upgrade, remove, logs (defaults to start)
-d : Custom root data directory (defaults to $DEFAULT_ROOT_DATA_DIR on Linux and $MAC_DEFAULT_ROOT_DATA_DIR on Mac)
-c : Clean local data directory. Delete the data directory on the host before creating the new ones
-f : Force removal if -c is passed (do not prompt)
-h : Show this usage
Examples
Prepare directories for Artifactory pro with default data directory
Start : sudo ./$SCRIPT_NAME -a start -c
Stop : sudo ./$SCRIPT_NAME -a stop
Restart : sudo ./$SCRIPT_NAME -a restart
Status : sudo ./$SCRIPT_NAME -a status
Remove : sudo ./$SCRIPT_NAME -a remove -c
Logs : sudo ./$SCRIPT_NAME -a logs
Upgrade : sudo ./$SCRIPT_NAME -a upgrade
END_USAGE
exit 1
}
setOS () {
OS_TYPE=$(uname)
if [[ ! $OS_TYPE =~ Darwin|Linux ]]; then
errorExit "This script can run on Mac or Linux only!"
fi
# On Mac, set DEFAULT_ROOT_DATA_DIR to ~/.jfrog
if [ "$OS_TYPE" == "Darwin" ]; then
DEFAULT_ROOT_DATA_DIR=${MAC_DEFAULT_ROOT_DATA_DIR}
fi
}
validateSudo () {
if [ "$OS_TYPE" == "Linux" ] && [ $EUID -ne 0 ]; then
errorExit "This script must be run as root or with sudo"
fi
}
# Process command line options. See usage above for supported options
processOptions() {
while getopts ":a:d:cfh" opt; do
case $opt in
a) # Action
ACTION=$OPTARG
[[ "$ACTION" =~ ^(start|stop|restart|status|upgrade|remove|logs)$ ]] || usage
;;
d) # Data dir
ROOT_DATA_DIR=$OPTARG
echo "Using a custom root data dir: $ROOT_DATA_DIR"
;;
c) # Clean
CLEAN=true
;;
f) # Force
FORCE=true
;;
h) # Usage
usage
;;
\?) # Unsupported
echo "ERROR: Option $OPTARG is not supported!"
usage
;;
esac
done
# Make sure mandatory parameters are set
if [ -z "$ACTION" ]; then
echo "No action passed. Defaulting to start clean"
ACTION=start
CLEAN=true
fi
# Set ROOT_DATA_DIR
if [ -z "$ROOT_DATA_DIR" ]; then
ROOT_DATA_DIR=${DEFAULT_ROOT_DATA_DIR}
fi
}
checkDocker () {
docker --version || errorExit "Unable to run docker"
docker-compose --version || errorExit "Unable to run docker-compose"
}
clean () {
if [ "$CLEAN" == "true" ] && [ -d ${ROOT_DATA_DIR} ]; then
local keep='n'
if [ "$FORCE" == "true" ]; then
keep='n'
else
echo
echo "An existing ${ROOT_DATA_DIR} was found. Do you want to keep it?"
echo "y (yes) : Keep existing ${ROOT_DATA_DIR}"
echo "n (no) : Remove it"
echo "a (abort) : Abort and exit"
echo -n "Select [y/n/a]: "
# Read from /dev/tty because of an issue when running curl | bash (does not wait for input)
read keep < /dev/tty
echo
fi
if [ "$keep" == "n" ]; then
echo "Removing existing ${ROOT_DATA_DIR}"
rm -rf ${ROOT_DATA_DIR}
DATA_REMOVED=true
elif [ "$keep" == "y" ]; then
echo "Keeping ${ROOT_DATA_DIR}"
else
echo "Aborting"
exit 1
fi
fi
}
createDirectories () {
if [ "$ACTION" == "start" ]; then
echo "Preparing ${ROOT_DATA_DIR}"
mkdir -p ${ROOT_DATA_DIR}/postgresql
mkdir -p ${ROOT_DATA_DIR}/artifactory/etc
mkdir -p ${ROOT_DATA_DIR}/nginx
# In case running on Mac with sudo, need to chown to sudo user
if [ -n "$SUDO_USER" ] && [ "$OS_TYPE" == "Darwin" ]; then
echo "Changing ownership of ${ROOT_DATA_DIR} to ${SUDO_USER}"
chown -R ${SUDO_USER} ${ROOT_DATA_DIR}
fi
fi
}
getDbDriver () {
if [ "$ACTION" == "start" ]; then
if [ ! -f ${ROOT_DATA_DIR}/${DB_DRIVER} ]; then
echo "Downloading the DB driver"
curl -# -o ${ROOT_DATA_DIR}/${DB_DRIVER} ${DB_DRIVER_URL} || errorExit "Getting ${DB_DRIVER} failed"
else
echo "DB driver already exists"
fi
fi
}
setDbPassword () {
if [ "$ACTION" == "start" ] && [ ! -f ${ROOT_DATA_DIR}/.dbpasswordcreated ] ; then
echo "Creating a new DB password"
TEMP_DB_PASSWORD=$(date +%s%N | shasum 2> /dev/null)
TEMP_DB_PASSWORD=${TEMP_DB_PASSWORD:0:12}
echo "Writing DB password to ${ROOT_DATA_DIR}/${DB_PASSWORD_FILE}"
echo -n "$TEMP_DB_PASSWORD" > ${ROOT_DATA_DIR}/${DB_PASSWORD_FILE}
touch ${ROOT_DATA_DIR}/.dbpasswordcreated
EXTRA_MSG="$EXTRA_MSG\nA password has been generated for the DB and saved in ${ROOT_DATA_DIR}/${DB_PASSWORD_FILE}"
fi
}
getArtifactoryComposeYaml () {
if [ "$FRESH_YML" != "true" ]; then
if [ -f ${COMPOSE_FILE} ]; then
echo "Removing existing ${COMPOSE_FILE} before getting a new one"
rm -f ${COMPOSE_FILE} || errorExit "Removing ${COMPOSE_FILE} failed"
fi
echo "Getting ${COMPOSE_FILE}"
curl -# -o ${COMPOSE_FILE} ${ART_COMPOSE_YML} || errorExit "Getting ${DB_DRIVER} failed"
echo "Preparing ${COMPOSE_FILE}"
# Do some editing
sed -i.bkp -e "s,~/${DB_DRIVER},${ROOT_DATA_DIR}/${DB_DRIVER},g" ${COMPOSE_FILE} || errorExit "Updating $COMPOSE_FILE failed"
if [ "$ROOT_DATA_DIR" != "$LINUX_ROOT_DATA_DIR" ]; then
echo "Setting host data dir"
sed -i.bkp -e "s,- ${LINUX_ROOT_DATA_DIR},- ${ROOT_DATA_DIR},g" ${COMPOSE_FILE} || errorExit "Updating $COMPOSE_FILE failed"
fi
if [ -n "$TEMP_DB_PASSWORD" ]; then
echo "Setting generated DB password"
sed -i.bkp -e "s,=password,=${TEMP_DB_PASSWORD},g" ${COMPOSE_FILE} || errorExit "Updating $COMPOSE_FILE failed"
fi
FRESH_YML=true
# Remove sed backup file
[ -f ${COMPOSE_FILE}.bkp ] && rm -f ${COMPOSE_FILE}.bkp
else
echo "Already have a new ${COMPOSE_FILE}"
fi
}
validateActions () {
case ${ACTION} in
start)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
# Potential upgrade
CLEAN=false
fi
;;
status)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
errorExit "You cannot check status and clean while system is already deployed."
fi
;;
stop)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
errorExit "You cannot stop and clean while system is deployed. Remove it first ($SCRIPT_NAME -a remove -c)."
fi
;;
restart)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
errorExit "You cannot restart and clean while system is already deployed."
fi
;;
upgrade)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
errorExit "You cannot upgrade and clean while system is already deployed."
fi
;;
remove)
;;
logs)
if [ "$(isDeployedAndCleanSet)" == "true" ]; then
errorExit "You cannot check logs and clean while system is already deployed."
fi
;;
esac
}
# Check if current setup is deployed. Return 1 for running
isDeployed () {
[ -f ${COMPOSE_FILE} ] || errorExit "Cannot check if system is deployed. ${COMPOSE_FILE} is missing"
local is_deployed=$(docker-compose -f ${COMPOSE_FILE} ps -q)
if [ -n "$is_deployed" ]; then
echo -n "true"
else
echo -n "false"
fi
}
isDeployedAndCleanSet () {
if [ "$(isDeployed)" == "true" ] && [ "$CLEAN" == "true" ]; then
echo -n "true"
else
echo -n "false"
fi
}
isNewerVersion () {
echo "Checking if we have a new version for upgrade"
local return_code=0
local deployed_version=$(docker ps -a --format "{{.Image}}" | grep /artifactory-pro | awk -F: '{print $2}')
echo "Deployed version is $deployed_version"
if [ "$ARTIFACTORY_VERSION" != "$deployed_version" ]; then
local lowest_version=$(echo -e "$deployed_version\n$ARTIFACTORY_VERSION" | sort -t. -k 1,1n -k 2,2n -k 3,3n | head -1)
if [ "$ARTIFACTORY_VERSION" == "$lowest_version" ]; then
errorExit "The current deployed version ($deployed_version) is higher than the new version ($ARTIFACTORY_VERSION)."
else
echo "The new version ($ARTIFACTORY_VERSION) is valid for upgrade"
return_code=1
fi
else
echo "Deployed version is identical to new version ($ARTIFACTORY_VERSION)."
fi
return ${return_code}
}
optionalUpgrade () {
echo "Artifactory is already deployed"
isNewerVersion
if [ $? -eq 0 ]; then
echo "Nothing to upgrade!"
return 0
fi
local sure='n'
if [ "$FORCE" == "true" ]; then
sure='y'
else
echo -n "Do you want to upgrade to the new version (${ARTIFACTORY_VERSION})? This will stop your Artifactory for the upgrade process [y/n]: "
read sure < /dev/tty
fi
if [ "$sure" == "y" ]; then
getArtifactoryComposeYaml
remove "true"
start
else
echo "Aborting"
exit 1
fi
}
start () {
# If already deployed, this might be an upgrade
if [ "$(isDeployed)" == "true" ]; then
optionalUpgrade
fi
echo "Starting Containers"
docker-compose -f ${COMPOSE_FILE} up -d --remove-orphans
}
status () {
echo "Containers status"
docker-compose -f ${COMPOSE_FILE} ps
}
stop () {
echo "Stopping Containers"
docker-compose -f ${COMPOSE_FILE} stop
}
restart () {
echo "Restarting Containers"
docker-compose -f ${COMPOSE_FILE} restart
}
remove () {
local sure='n'
if [ "$DATA_REMOVED" == "true" ] || [ "$1" == "true" ] || [ "$FORCE" == "true" ]; then
sure='y'
else
echo -n "Are you sure you want to stop and remove Artifactory [y/n]: "
read sure < /dev/tty
fi
if [ "$sure" == "y" ]; then
stop
echo "Removing Containers"
docker-compose -f ${COMPOSE_FILE} rm --force
else
echo "Aborting"
exit 1
fi
}
upgrade () {
if [ "$(isDeployed)" == "true" ]; then
optionalUpgrade
else
errorExit "There is no deployed Artifactory. Nothing to upgrade."
fi
}
logs () {
echo "Getting container logs"
docker-compose -f ${COMPOSE_FILE} logs -t
}
showMsg () {
if [ "$ACTION" == "start" ]; then
echo
echo "########################################################################"
echo "Setup is complete."
echo "Host directory $ROOT_DATA_DIR has all data and configurations."
echo -e "$EXTRA_MSG"
echo "Point your browser to https://<server>/artifactory/ or http://<server>/artifactory/"
echo "########################################################################"
echo
fi
}
############ Main #############
setOS
validateSudo
processOptions $*
checkDocker
validateActions
clean
createDirectories
getDbDriver
setDbPassword
getArtifactoryComposeYaml
eval ${ACTION}
showMsg