-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprepare
executable file
·293 lines (250 loc) · 7.02 KB
/
prepare
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
#!/bin/bash -
#===============================================================================
#
# FILE: prepare
#
# USAGE: ./prepare -i <app-name> -r /opt -u
# ./prepare -i <app-name> -r /opt
# ./prepare -i <app-name>
# ./prepare -f
#
# DESCRIPTION: Initialize an aviumlabs Phoenix Framework docker project with
# database support
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: The Avium Labs Phoenix Framework docker project is setup
# as a multi-stage process.
# First stage:
# Initialize Phoenix Framework project
# Second stage:
# Configure dev.exs for docker
# Configure .env for app
# AUTHOR: Michael Konrad (2023),
# ORGANIZATION: Avium Labs LLC
# CREATED: 04/05/2023 10:42
# REVISION: ---
#===============================================================================
set -o nounset # Treat unset variables as an error
IFS=$'\n\t'
# Defaults
ENV_FILE=$(pwd)/.env
DB_SECRET_FILE=$(pwd)/.secret_db
APP_CONTAINER_ROOT=/opt
MIX_ENV=dev # dev, test, prod
# Help
usage() {
printf "\n"
printf "A script to automate the steps to configure the\n"
printf "docker containers based on this docker compose file.\n"
printf "\n"
printf "Project preparation is a two step process: \n"
printf "Step 1: Initialize Phoenix Framework project docker root and\n"
printf " the application name.\n"
printf "\n"
printf "Step 2: Finalize the Phoenix Framework project, run\n"
printf " ecto.create, and docker compose up.\n"
printf "\n"
printf "$0 -i <app_name> [-r </app/container/root>] [-u]\n"
printf "$0 -f\n"
printf "\n Details: \n"
printf " -i specify the name of the application.\n"
printf " -r optionally specify the application's container root\n"
printf " directory, defaults to /opt.\n"
printf " -u optionally specify this application is configured as\n"
printf " a Phoneix umbrella application.\n"
printf " -f finalize the Phoenix Framework project,\n"
printf " updates the config/dev.exs file and the\n"
printf " docker environment file.\n"
printf "\n"
printf " This script by default generates the docker environment \n"
printf " file, as .env file in the current working directory.\n"
printf "\n\n"
printf "Initialize example:\n"
printf " * $0 -i gutentag -r /opt -u\n"
printf " * $0 -i gutentag -r /app\n"
printf " * $0 -i gutentag\n"
printf "\n"
printf "Finalize example: $0 -f\n"
printf "\n"
exit 1
}
FINIT='false'
INIT='false'
UMBRELLA='false'
# Script options
optstring=":i:r:fuh"
while getopts ${optstring} arg; do
case ${arg} in
f)
FINIT='true'
;;
i)
INIT='true'
APP_NAME=${OPTARG};
;;
r)
INIT='true'
APP_CONTAINER_ROOT=${OPTARG}
;;
u)
INIT='true'
UMBRELLA='true'
;;
h)
usage
;;
:)
printf "Missing required value for -$OPTARG\n"
usage
;;
\?)
printf "Invalid option... -${OPTARG}\n"
usage
;;
esac
done
# Main function to run script operations
main() {
if [[ ${FINIT} == true ]]; then
finalize
elif [[ ${INIT} == true ]]; then
initialize
fi
}
# Generate a random 14 character password
gen_rand_pass() {
if [[ "$OSTYPE" == "darwin"* ]]; then
PPWD=$(date +%s | shasum -a 256 | base64 | head -c14)
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
PPWD=$(date +%s | sha256sum | base64 | head -c14)
fi
}
# Generate the docker environment file if it does not exist
gen_env_file() {
if [ ! -f $ENV_FILE ]; then
cat > $ENV_FILE <<EnvFile
# app variables
APP_CONTAINER_ROOT=$APP_CONTAINER_ROOT
APP_NAME=$APP_NAME
MIX_ENV=$MIX_ENV
WORKINGDIR=$APP_CONTAINER_ROOT
UMBRELLA=$UMBRELLA
EnvFile
else
printf "Environment file is already existing.\n"
exit 1
fi
}
gen_db_secret_file() {
# Generate a random password for Postgres
gen_rand_pass
if [ ! -f $DB_SECRET_FILE ]; then
cat > $DB_SECRET_FILE <<DbFile
$PPWD
DbFile
else
printf "DB secret file is already existing.\n"
exit 1
fi
}
# Report an error when sed fails
sed_error() {
printf "Exiting, failed to update... $update_file. Please file a \
bug report.\n"
exit 1
}
# Initialize the Phoenix Framework project
initialize() {
if [ -n $APP_NAME ]; then
printf "Initializing Phoenix Framework project...\n"
printf "Application container root............... $APP_CONTAINER_ROOT\n"
printf "Application name......................... $APP_NAME\n"
# Generate the initial docker environment file
gen_env_file
# Generate database secret
gen_db_secret_file
if [[ ${UMBRELLA} == true ]]; then
printf "Running phx.new umbrella...\n"
docker compose run --rm app mix phx.new --umbrella --install $APP_NAME --binary-id
else
printf "Running phx.new...\n"
docker compose run --rm app mix phx.new --install $APP_NAME --binary-id
fi
else
usage
fi
}
# Finalize the Phoenix Framework configuration and call mix ecto.create
finalize() {
if [ ! -f "$ENV_FILE" ]; then
usage
else
lc=0
while IFS=$'=' read -r avar aval; do
if [[ "$avar" == "APP_CONTAINER_ROOT"* ]]; then
APP_CONTAINER_ROOT=$aval
fi
if [[ "$avar" == "APP_NAME"* ]]; then
APP_NAME=$aval
fi
if [[ "$avar" == "UMBRELLA"* ]]; then
UMBRELLA=$aval
fi
if [[ "$avar" == "MIX_ENV"* ]]; then
MIX_ENV=$aval
fi
done < $ENV_FILE
if [ ! -f "$DB_SECRET_FILE" ]; then
usage
else
while read -r secret; do
PPWD="$secret"
done < $DB_SECRET_FILE
fi
# Set the docker working directory
# This is the directory where the app will live in the
# docker container
if [[ ${UMBRELLA} == true ]]; then
APP_NAME="$APP_NAME"_umbrella
fi
WORKINGDIR="$APP_CONTAINER_ROOT/$APP_NAME"
# Password format for database "<password>",
DB_PPWD=\"$PPWD\",
# Configure dev.exs for docker
update_file="src/$APP_NAME/config/dev.exs"
sed -i '' -e "s|\(password: \).*|\1"$DB_PPWD"|" \
-e 's|"localhost"|"db"|' \
-e 's|127, 0, 0, 1|0, 0, 0, 0|' $update_file
# sed varies between operating systems, check if it failed
if [ $? -gt 0 ]; then
sed_error
fi
# Configure test.exs for docker
update_file="src/$APP_NAME/config/test.exs"
sed -i '' -e "s|\(password: \).*|\1"$DB_PPWD"|" \
-e 's|"localhost"|"db"|' \
-e 's|127, 0, 0, 1|0, 0, 0, 0|' $update_file
# sed varies between operating systems, check if it failed
if [ $? -gt 0 ]; then
sed_error
fi
# Update the WORKINGDIR in the env file
update_file=$ENV_FILE
sed -i '' -e "s|\(WORKINGDIR=\).*|\1"$WORKINGDIR"|" \
$update_file
# sed varies between operating systems, check if it failed
if [ $? -gt 0 ]; then
sed_error
fi
# Run mix ecto.create
cd "src/$APP_NAME"
printf "Running mix ecto.create...\n"
docker compose run --rm app mix ecto.create
# Start the application
printf "Running docker compose up; press ctrl-c to stop...\n"
printf "\n"
docker compose up
fi
}
main