-
Notifications
You must be signed in to change notification settings - Fork 3
/
lucy
executable file
·380 lines (307 loc) · 9.13 KB
/
lucy
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
#!/bin/bash
# License: https://raw.githubusercontent.com/pr3d4t0r/lucyfer/master/LICENSE.txt
set -e
# +++ constants +++
DEFAULT_SERVICE="lucyfer_service"
KALLISTO_HUB_VERSION="3.6.4"
LUCYFER_GITHUB_FILES=(
"README-1ST.ipynb"
"README-Kotlin.ipynb"
"lucy" )
LUCYFER_GITHUB_PATH="https://raw.githubusercontent.com/pr3d4t0r/lucyfer/master"
LUCYFER_HUB_VERSION="3.6.4"
# *** functions ***
die() {
echo "$1"
exit "$2"
} # die
assertActionInCLI() {
local syntax="syntax: lucy env | neuter | start | stop | status | token | update | version"
[[ -z "$1" ]] && die "Command missing; $syntax" 8
case "$1" in
"env")
;;
"neuter")
;;
"start")
;;
"stop")
;;
"status")
;;
"token")
;;
"update")
;;
"version")
;;
*)
die "$syntax" 9
;;
esac
} # assertActionInCLI
assertDockerServiceIsRunning() {
local uname=$(uname)
local message="Docker daemon not running"
case "$uname" in
"Darwin")
[[ -n $(ps aux | awk '/Docker\.app/ || /Docker Desktop\.app/') ]] || die "$message" 4
;;
"Linux")
die "Linux not supported yet" 6
;;
*)
die "$uname not supported" 3
esac
} # assertDockerServiceIsRunning
assertDockerIsAvailable() {
which docker > /dev/null || die "docker unavailable or not in path" 1
} # assertDockerIsAvailable
assertDockerComposeFileExists() {
if [[ -z "$LUCYFER_COMPOSE" ]]
then
export LUCYFER_COMPOSE='lucyfer-compose.yaml'
fi
[[ -e "$LUCYFER_COMPOSE" ]] || die "$LUCYFER_COMPOSE is not present in pwd == $(pwd)" 2
} # assertDockerComposeFileExists
assertComponentExists() {
# Make a dynamic list at some point?
case "$container" in
"")
;;
"lucyfer")
;;
"kallisto")
;;
*)
awk -F "'" 'BEGIN { print("Available lucyfer containers:\n"); } /container_name/ { printf("* %s\n", $2); } END { print(""); }' "$LUCYFER_COMPOSE"
die "Container $container not found" 11
esac
} # assertComponentExists
assertWorkspaceExists() {
if [[ -z "$LUCYFER_WORKSPACE" ]]
then
export LUCYFER_WORKSPACE="$(pwd)"
echo "LUCYFER_WORKSPACE=$LUCYFER_WORKSPACE"
fi
} # assertWorkspaceExists
assertDataRepositoryExists() {
if [[ -z "$KALLISTO_DATA" ]]
then
export KALLISTO_DATA="$(pwd)/data"
echo "KALLISTO_DATA=$KALLISTO_DATA"
fi
mkdir -p "$KALLISTO_DATA"
} # assertDataRepositoryExists
setOwnership() {
# Set ownership to the correct user:group to avoid conflicts
# between the internal Docker container user names and the
# host's.
#
# This script resolves to the userID:groupID of the account
# from whence it was invoked.
#
# Documented method because Docker permissions and ownership
# kinda suck.
export BLAZEGRAPH_GID=$(id -g)
export BLAZEGRAPH_UID=$(id -u)
export JUPYTER_LAB_GID=$(id -g)
export JUPYTER_LAB_UID=$(id -u)
} # setOwnership
setHostPorts() {
if [[ -z "$LUCYFER_PORT" ]]
then
export LUCYFER_PORT="8805"
fi
if [[ -z "$KALLISTO_PORT" ]]
then
export KALLISTO_PORT="8808"
fi
} # setHostPorts
setOpenOnStart() {
if [[ -z "$LUCYFER_OPEN_ON_START" ]]
then
LUCYFER_OPEN_ON_START="yes"
fi
} # setOpenOnStart
_snuffContainer() {
[[ -n "$1" ]] || die "container name not specified in _snuffContainer()" 5
local container=$(docker ps -a | awk -v "containerName=$1" '$0 ~ containerName { print($NF); }')
if [[ -n "$container" ]]
then
docker rm -f "$container"
fi
} # _snuffContainer
resolveImageByPlatform() {
local platform=$(uname -a | awk 'BEGIN { m = "ARM64"; i = "X86"; } { if ($14 ~ m) print(m); if ($14 ~ i) print(i); }')
case "$platform" in
"ARM64")
export KALLISTO_IMAGE="pr3d4t0r/kallisto-m:$KALLISTO_HUB_VERSION"
export LUCYFER_IMAGE="pr3d4t0r/lucyfer-m:$LUCYFER_HUB_VERSION"
;;
"X86")
export KALLISTO_IMAGE="pr3d4t0r/kallisto:$KALLISTO_HUB_VERSION"
export LUCYFER_IMAGE="pr3d4t0r/lucyfer:$LUCYFER_HUB_VERSION"
;;
*)
die "host platform not supported" 7
;;
esac
} # resolveImageByPlatform
showLucyferLab() {
echo ""
docker compose -f "$LUCYFER_COMPOSE" ps -a
} # showLucyferLab
showToken() {
local token
if [[ ! -e ".jupyter/jupyter_server_config.json" ]]
then
token=$(docker logs lucyfer 2>&1 | awk -F "?" '/http:/ { gsub("token=", "", $NF); printf($NF); exit(0); }')
if [[ -n "$token" ]]
then
printf "\nLucyfer authentication token = $token\n"
case $(uname) in
"Darwin")
echo " The authentication token is available on the clipboard; Cmd-V to paste"
echo "$token" | pbcopy
;;
esac
fi
else
printf "\nUse the password to log on to Lucyfer; no token available\n"
fi
} # showToken
runLucyferLab() {
_snuffContainer "lucyfer"
_snuffContainer "kallisto"
echo ""
env | awk '/LUCYFER/ || /JUPYTER/ || /HOME/ || /BLAZE/ || /KALLISTO/' | sort
if [[ -n "$container" ]]
then
local service="$container""_service"
docker compose -f "$LUCYFER_COMPOSE" up --remove-orphans --no-recreate -d "$service" || docker compose rm -f
else
docker compose -f "$LUCYFER_COMPOSE" up --remove-orphans --no-recreate -d "$DEFAULT_SERVICE" || docker compose rm -f
fi
# TODO: replace with an actual check to see if the container started/is healthy
sleep 10
showLucyferLab
showToken
[[ "yes" = "$LUCYFER_OPEN_ON_START" ]] && open "http://localhost:$LUCYFER_PORT"
} # runLucyferLab
killLucyferLab() {
echo ""
env | awk '/LUCYFER/ || /JUPYTER/ || /HOME/ || /BLAZE/ || /KALLISTO/' | sort
if [[ -n "$container" ]]
then
local service="$container""_service"
docker compose -f "$LUCYFER_COMPOSE" stop "$service"
else
docker compose -f "$LUCYFER_COMPOSE" stop
fi
showLucyferLab
} # killLucyferLab
displayEnvironment() {
echo "export LUCYFER_WORKSPACE=$(pwd)"
echo "export KALLISTO_DATA=$(pwd)/data"
} # displayEnvironment
_fetchFileFrom() {
local fullURL="$1"
local targetLocation="$2"
if [[ -n "$(which wget)" ]]
then
wget -O "$targetLocation" "$fullURL"
elif [[ -n "$(which curl)" ]]
then
curl -o "$targetLocation" "$fullURL"
else
die "Neither wget nor cURL are available; install either and retry" 10
fi
} # _fetchFileFrom
update() {
local fileName
local fullURL
local kallistoNewest
local localPath
local lucyNewest
for fileName in ${LUCYFER_GITHUB_FILES[@]}
do
fullURL="$LUCYFER_GITHUB_PATH/$fileName"
localPath="./$fileName"
if [[ -f "$localPath" ]]
then
echo ">> $fullURL"
echo [[ -e "$localPath" ]] && rm -f "$localPath"
_fetchFileFrom "$fullURL" "$localPath"
echo ""
fi
done
chmod +x "./lucy"
# Pull corresponding image from the hub:
kallistoNewest=$(awk -v "i=$KALLISTO_IMAGE" -F "\"" '/KALLISTO_HUB_VERSION=/ && !/awk/ { split(i, b, ":"); printf("%s:%s\n", b[1], $2); }' ./lucy)
lucyNewest=$(awk -v "i=$LUCYFER_IMAGE" -F "\"" '/LUCYFER_HUB_VERSION=/ && !/awk/ { split(i, b, ":"); printf("%s:%s\n", b[1], $2); }' ./lucy)
docker pull "$lucyNewest"
docker pull "$kallistoNewest"
echo "Lucyfer update complete"
} # update
version() {
printf "\nLucyfer version: $LUCYFER_HUB_VERSION\n"
} # version
neuterInstallation() {
local answer
read -p "Are you sure you want to neuter the Lucyfer installation? yes/NO " answer
if [[ "$answer" == "yes" ]]
then
./lucy stop
docker rm -f lucyfer kallisto
rm -vf ./.bash* ./.vimrc ./.viminfo ./kallisto-compose.yaml ./lucyfer-compose.yaml ./mornyng-compose.yaml ./.lesshst ./lucy ./.profile
rm -Rvf "./.local" "./.ipython" "./.vim" "./.ssh" "./.idea" "./.m2" "./.npm" "./.config" "./.cache" "./.jupyter" "./.ipynb_checkpoints"
rm -Rfv ./README-1ST.ipynb ./README-Kotlin.ipynb
docker ps -a
echo "Lucyfer was neutered"
else
echo "Lucyfer neutering aborted - good choice"
fi
exit 0
} # neuterInstallation
# *** main ***
action="$1"
container="$2"
assertActionInCLI "$action"
assertDockerServiceIsRunning
assertDockerIsAvailable
assertDockerComposeFileExists
assertComponentExists
assertWorkspaceExists
assertDataRepositoryExists
setOwnership
setHostPorts
setOpenOnStart
resolveImageByPlatform
case "$action" in
"env")
displayEnvironment
;;
"neuter")
neuterInstallation
;;
"start")
runLucyferLab
;;
"status")
showLucyferLab
;;
"stop")
killLucyferLab
;;
"token")
showToken
;;
"update")
update
;;
"version")
version
;;
esac
echo ""