-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathrun
executable file
·336 lines (303 loc) · 10.6 KB
/
run
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
#!/bin/bash
# utility script / entry point for the repo
main__(){
while (( $# > 0 )); do
rest=${@:2}
case $1 in
help ) show_help; exit 0 ;; # show help for commands
init ) # install docker and docker-compose on ubuntu ( must be run as sudo )
sudo bash -c "$(declare -f install_docker)
install_docker $(whoami)"
install_certificates ;;
prune ) node_modules_prune ;; # clear webpack node_modules volume
enable ) enable_service ;; # enable systemd service file for web server - starts all docker images
reload ) (2>&1 reload_service > reload-service.log) &;; # reload service when code changed
dc ) docker-compose $rest; exit ;; # docker-compose [...args]
da ) docker-compose run --rm web django-admin $rest; exit ;; # django-admin [...args]
cbrenew ) renew_certificates ;; # renew certbot certificates
cbinit ) install_certificates ;; # install certbot certificates
pgdump ) dump_postgres ;; # dump postgresql database
pgload ) load_postgres $rest; exit;; # load database from dump file [filename]
rddump ) dump_redis ;; # dump redis database
rdload ) load_redis $rest; exit;; # load redis database
djbuild ) build_django ;; # download and build all images, migrate database
webpack ) docker-compose run --rm webpack ${rest:-bash}; exit;; # login to webpack container as default user
build ) webpack_build ;; # build css+js client bundles and express bundle;
storyb ) docker-compose run --rm --name storybook -p 9001:9001 webpack storybook ;; # start storybook on port 9001
sbdep ) cd webpack; npm run deploy-storybook ;; # build and deploy storybook
pyup ) cd django; pip-compile --upgrade ;; # pip update python packages
repl ) docker-compose run --rm web django-admin shell_plus --quiet-load ;; # django repl shell
django ) docker-compose run --rm -u django web ${rest:-bash}; exit ;; # login to django container as default user
root ) docker-compose run --rm web ${rest:-bash}; exit ;; # login to django container as root
pytest ) # run python tests
testing; docker-compose run --rm --name testf -u django web pytest -f -x --ff $rest; exit ;;
flower ) docker-compose run --rm --name flower -d -p 5555:5555 celery flower ;; # start celery flower on port 5555
jupyter ) start_jupyter ;; # start jupyter server for django on port 8888
fake ) docker-compose run --rm web django-admin fake_content -c10 -s50 ;; # create fake data in django database
static ) collect_static_files --ignore ;; # run django collectstatic
upd ) docker-compose up -d ;; # start all docker images in daemon mode
logs ) docker-compose logs --tail=50 -f $rest ; exit ;; # show docker logs
testing ) # testing settings
testing; echo 'testing settings' $IMAGE_VERSION $BRANCH;;
prod ) # production settings
production_settings; echo 'production settings' $IMAGE_VERSION $BRANCH;;
dev ) # development settings
echo "development settings" ;;
lint ) lint_javascript; lint_python ;; # lint all files commited
test ) run_tests ;; # run pytest and jest
tags ) build_tags ;; # collect ctags for python and js
precom ) main__ lint tags test; exit 0 ;; # run before git commit
* ) show_help ${@:1}; exit 1 ;;
esac;
shift 1;
done
}
build_tags() {
if_installed ctags -R ./django ./webpack/src
echo "collected tags > $PWD/tags"
}
webpack_build() {
echo 'build webpack for production'
production_settings
docker-compose run --rm webpack build
}
collect_static_files() {
if [[ $1 == '--ignore' ]]; then
# ignore some apps that probably already are collected
IGNORE='admin debug_toolbar rest_framework django_extensions core'
shift
args="$(printf -- "-i%s " $IGNORE)$@"
else
args="$@"
fi
docker-compose run --rm web django-admin collectstatic --noinput $args
}
production_settings() {
BRANCH=$(git status | awk '/On branch/{print $3}')
export BRANCH=${TRAVIS_BRANCH:-$BRANCH}
# if [[ $BRANCH == 'master' ]]; then
# export IMAGE_VERSION=$(git tag --merged | tail -n1)
# fi
export COMPOSE_FILE=docker-compose.yml:docker-compose.production.yml
}
testing() {
production_settings
# if [[ $BRANCH == 'master' ]]; then
# export IMAGE_VERSION=latest
# fi
export COMPOSE_FILE=docker-compose.yml:docker-compose.testing.yml
}
run_tests() {
testing
docker-compose run --rm webpack test || exit 1
docker-compose run --rm -u django web pytest --create-db \
-p no:cacheprovider || exit 1
}
show_help() {
# ansi codes
esc=$(printf '\033')
yellow="$esc[33;1m"
red="$esc[31;1m"
bold="$esc[1m"
reset="$esc[0m"
# help output
printf "\n usage: %s [...commmands]\n\n" "$0"
cat run \
| sed -n '/^main__()/,$p;/^}/q'\
| awk '/[a-zA-Z] *\) /{print}/case/{p=1}'\
| sed 's/; exit//' | sed 's/;;//'\
| sed "s/).*#\(.*\)$/)$yellow\1$reset/"\
| sed "s/^ *\(\w* *\))/ $bold\1$reset/"\
| sort
if [[ $# > 0 ]]; then
printf "\n %sunknown command: %s%s\n" "$red" "$*" "$reset" >&2
fi
}
lint_javascript() {
cd webpack
files=$(git status -s . \
| awk '/^ *[AM].*\.(json|js|jsx|scss)/ {print $2}')
cd ..
if [[ -n $files ]]; then
echo 'linting changed webpack files'
docker-compose run --rm webpack lint $files
else
echo 'no changed webpack files'
fi
}
lint_python() {
cd django
files=$(git status -s . | awk '/^ *[AM].*\.py/ {print $2}')
cd ..
if [[ -n $files ]]; then
echo 'linting changed django files'
docker-compose run --rm django lint $files
else
echo 'no changed django files'
fi
}
dump_redis() {
DUMP=$(date +"dump.%d-%m-%Y_%H.%M.%S.rdb")
docker run -udjango --rm --volumes-from tassen_redis_1 -v $(pwd):/backup \
universitas/django cp /data/dump.rdb /backup/$DUMP
}
load_redis() {
dumpfile=$(ls *.rdb -1t 2>/dev/null | head -n1)
dumpfile=${1:-$dumpfile}
[[ -e $dumpfile ]] || exit 1
echo "found database dump: $dumpfile"
cp $dumpfile __dump.rdb
docker-compose stop redis
docker run --rm --volumes-from tassen_redis_1 -v $(pwd):/backup \
universitas/django cp /backup/__dump.rdb /data/dump.rdb
docker-compose start redis
rm __dump.rdb
}
load_postgres() {
dumpfile=$(ls *.sql -1t 2>/dev/null | head -n1)
dumpfile=${1:-$dumpfile}
[[ -e $dumpfile ]] || exit 1
echo "found database dump: $dumpfile"
cp $dumpfile django/dbdump.sql
# loading data
docker-compose down
docker-compose run --rm web load_db
# cleanup
rm django/dbdump.sql
echo "done"
}
dump_postgres() {
DUMP=$(date +"pgdump_%d-%m-%Y_%H.%M.%S.sql")
docker-compose up -d postgres
echo "dumping database to $DUMP"
docker-compose exec postgres pg_dump --no-owner -U postgres -d postgres > $DUMP
}
if_installed() {
# execute only if the program is installed
if command -v "$1" >/dev/null 2>&1; then
eval $@
else
echo "$1 not found. Skipping" >&2
return 127
fi
}
reload_service() {
echo "--- reload start $(date -Iseconds) ---"
production_settings
webpack_build
docker-compose run --rm web django-admin migrate
docker-compose run --rm web django-admin collectstatic --clear --noinput
docker-compose restart express celery celerybeat
# The pipe is owned by user 1000 (django inside uwsgi/web docker container)
echo r | sudo -u#1000 tee ./fifo/uwsgi >/dev/null
echo '--- reload OK ---'
}
enable_service() {
# must run as root
if [[ -e /lib/systemd/system/universitas.service ]]; then
echo "reload systemd service"
sudo systemctl daemon-reload
sudo systemctl reload universitas.service
else
echo "enable systemd service"
sudo sh -c "
ln -s $PWD/universitas.service /lib/systemd/system/
systemctl deamon-reload
systemctl enable universitas.service
systemctl start universitas.service"
fi
}
start_jupyter() {
echo "starting jupyter on http://localhost:8888"
( sleep 12; sensible-browser http://localhost:8888 &> /dev/null)&
docker-compose run --rm --name jupyter -p 8888:8888 web jupyter
}
build_django() {
echo "building"
docker-compose build
docker-compose run --rm web django-admin migrate
docker-compose run --rm web django-admin collectstatic --noinput
}
install_docker() {
# install docker and docker-compose on ubuntu
[ $UID = 0 ] || { echo 'must run as root' >&2; exit 1; }
USERNAME=$1
apt-get install -y \
apt-transport-https \
ca-certificates \
software-properties-common \
python3-pip
pip3 install -U docker-compose
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce
groupadd -f docker
if [[ -z $USERNAME ]]; then
usermod -aG docker $USERNAME
fi
systemctl enable docker
}
install_certificates() {
production_settings
docker-compose run -p80:80 certbot \
--noninteractive \
--agree-tos \
--email=$CERTBOT_EMAIL \
--domains=$CERTBOT_DOMAINS \
--cert-name=universitas \
--standalone \
certonly
}
renew_certificates() {
production_settings
date -uIhours
docker-compose run certbot \
--noninteractive \
--agree-tos \
--email=$CERTBOT_EMAIL \
--domains=$CERTBOT_DOMAINS \
--cert-name=universitas \
--webroot \
--webroot-path=/srv/ \
--keep-until-expiring \
certonly
docker-compose exec nginx nginx -s reload
}
node_modules_prune() {
# this will clean up the dev_node_modules docker volume
# should be done when the webpack image has been changed
name='node_modules'
volumes=$( docker volume ls --quiet \
--filter label=com.docker.compose.volume=$name )
# docker-compose pull webpack
for volume in $volumes; do
local_dir=$( docker volume inspect --format '{{ .Options.device }}' "$volume" )
containers=$( docker ps -qa --filter volume="$volume" )
printf "deleting volume '$volume'\nand containers\n $containers\n"
[[ -n "$containers" ]] && docker rm -f $containers >/dev/null
docker volume rm "$volume" >/dev/null
rm -rf "$local_dir"
mkdir -p "$local_dir"
done
[[ -z $volumes ]] && printf 'docker volume "%s" not found\n' $name >&2
}
cd $(dirname $0)
[[ ! -f django/local.env ]] && echo "# Add environment variables here" > django/local.env
source django/local.env
mkdir -p \
./webpack/node_modules/\
./django/venv/\
./volumes/static\
./volumes/media/\
./volumes/staging/\
./volumes/ssh/\
./volumes/logs/\
./volumes/certificates/
unset CDPATH
export COMPOSE_HTTP_TIMEOUT=6000
export GIT_SHA=$(git rev-parse HEAD)
export COMPOSE_FILE=docker-compose.yml:docker-compose.dev.yml
export AWS_ENABLED=$AWS_ENABLED
export IMAGE_VERSION=latest
main__ $@