-
Notifications
You must be signed in to change notification settings - Fork 8
/
internal-functions
289 lines (253 loc) · 10.4 KB
/
internal-functions
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
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/discourse/config"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/config/functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
fn-get-input() {
declare MESSAGE="$1" DEFAULT="$2"
read -rp "$MESSAGE [$DEFAULT]: " input
if [[ -z "$input" ]]; then
echo "$DEFAULT"
else
echo "$input"
fi
}
fn-get-env-config() {
declare KEY="$1"
local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
local GET_ENV_CONFIG_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/get-env-config"
local CONFIG
CONFIG=$("$GET_ENV_CONFIG_BIN_PATH" "$CONFIG_FILE_PATH" "$KEY" 2> /dev/null)
[[ -z "$CONFIG" ]] && dokku_log_fail "Config key not found: $KEY"
echo "$CONFIG"
}
fn-update-discourse-build-files() {
if [[ -d "$DISCOURSE_DOCKER_IMAGE_ROOT" ]]; then
cd "$DISCOURSE_DOCKER_IMAGE_ROOT"
dokku_log_info1 "Updating the discourse image build files"
git pull origin main
else
dokku_log_info1 "Cloning the discourse image build files"
git clone https://github.com/discourse/discourse_docker.git "$DISCOURSE_DOCKER_IMAGE_ROOT"
fi
}
fn-update-discourse-config-set-volumes() {
declare APP_NAME="$1" APP_STORAGE_ROOT="$2"
local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
local SET_VOLUMES_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/set-volumes"
local UPDATED_CONFIG
UPDATED_CONFIG=$("$SET_VOLUMES_BIN_PATH" "$CONFIG_FILE_PATH" "$APP_STORAGE_ROOT" 2> /dev/null)
[[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error setting volumes in config"
echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH"
dokku_log_info1 "Updated '$APP_NAME' discourse volumes"
}
fn-update-discourse-config-env() {
declare APP_NAME="$1" \
HOSTNAME="$2" \
DEVELOPER_EMAILS="$3" \
SMTP_ADDRESS="$4" \
SMTP_PORT="$5" \
SMTP_USER_NAME="$6" \
SMTP_PASSWORD="$7"
local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
local UPDATE_ENV_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/update-env"
local UPDATED_CONFIG
UPDATED_CONFIG=$("$UPDATE_ENV_BIN_PATH" "$CONFIG_FILE_PATH" "$HOSTNAME" "$DEVELOPER_EMAILS" "$SMTP_ADDRESS" "$SMTP_PORT" "$SMTP_USER_NAME" "$SMTP_PASSWORD" 2> /dev/null)
[[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error setting env in config"
echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH"
dokku_log_info1 "Updated '$APP_NAME' discourse env"
}
fn-create-default-discourse-container-config() {
declare APP_NAME="$1"
mkdir -p "$DOKKU_ROOT/$APP_NAME"
local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
if [[ ! -f "$CONFIG_FILE_PATH" ]]; then
cp "$PLUGIN_ROOT_PATH/containers/$CONTAINER_TYPE.yml" "$CONFIG_FILE_PATH"
fi
}
fn-update-discourse-container-config() {
declare APP_NAME="$1" \
APP_STORAGE_ROOT="$2" \
HOSTNAME="$3" \
DEVELOPER_EMAILS="$4" \
SMTP_ADDRESS="$5" \
SMTP_PORT="$6" \
SMTP_USER_NAME="$7" \
SMTP_PASSWORD="$8"
fn-update-discourse-config-env \
"$APP_NAME" \
"$HOSTNAME" \
"$DEVELOPER_EMAILS" \
"$SMTP_ADDRESS" \
"$SMTP_PORT" \
"$SMTP_USER_NAME" \
"$SMTP_PASSWORD"
fn-update-discourse-config-set-volumes "$APP_NAME" "$APP_STORAGE_ROOT"
local CONFIG_FILE_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
dokku_log_info2 "Container config updated at location $CONFIG_FILE_PATH"
}
fn-version-greater-equal() {
local DOKKU_VERSION;
DOKKU_VERSION=$(fn-get-dokku-version)
if [[ -z "$DOKKU_VERSION" ]]; then
dokku_log_fail "Unable to determine dokku's version"
fi
local DOKKU_VERSION_NUMBER
DOKKU_VERSION_NUMBER=${DOKKU_VERSION//^v/}
printf '%s\n%s\n' "$1" "$DOKKU_VERSION_NUMBER" | sort -V -C
}
fn-ps-stop() {
declare APP_NAME="$1"
if fn-version-greater-equal "0.22.0"; then
dokku ps:stop "$APP_NAME"
else
ps_stop "$APP_NAME"
fi
}
fn-build-image() {
declare APP_NAME="$1"
[[ -n $("$DOCKER_BIN" ps -q -f ancestor="dokku/$APP_NAME") ]] && fn-ps-stop "$APP_NAME"
local APP_IMAGE_NAME="dokku/$APP_NAME:latest"
dokku_log_info1 "Building the discourse docker image, this can take a while..."
local CONTAINER_CONFIG_PATH="$DOKKU_ROOT/$APP_NAME/$DISCOURSE_CONTAINER_CONFIG_NAME.yml"
if [[ ! -f "$CONTAINER_CONFIG_PATH" ]]; then
dokku_log_fail "Discourse conainer config not found at location $CONTAINER_CONFIG_PATH"
fi
ln -sf "$CONTAINER_CONFIG_PATH" "$DISCOURSE_DOCKER_IMAGE_ROOT/containers/$CONTAINER_TYPE-$APP_NAME.yml"
"$DISCOURSE_DOCKER_IMAGE_ROOT/launcher" bootstrap "$CONTAINER_TYPE-$APP_NAME"
local DISCOURSE_IMAGE_NAME="local_discourse/$CONTAINER_TYPE-$APP_NAME"
"$DOCKER_BIN" tag "$DISCOURSE_IMAGE_NAME:latest" "$APP_IMAGE_NAME"
"$DOCKER_BIN" rmi "$DISCOURSE_IMAGE_NAME"
}
fn-discourse-config-add-plugin() {
declare APP_NAME="$1" PLUGIN_GIT_URL="$2"
local CONFIG_FILE_PATH="$DISCOURSE_DOCKER_IMAGE_ROOT/containers/$CONTAINER_TYPE-$APP_NAME.yml"
local ADD_PLUGIN_BIN_PATH="$PLUGIN_AVAILABLE_PATH/discourse/containers/add-plugin"
local UPDATED_CONFIG
UPDATED_CONFIG=$("$ADD_PLUGIN_BIN_PATH" "$CONFIG_FILE_PATH" "$PLUGIN_GIT_URL" 2> /dev/null)
[[ -z "$UPDATED_CONFIG" ]] && dokku_log_fail "Error adding plugin to config"
echo "$UPDATED_CONFIG" > "$CONFIG_FILE_PATH"
dokku_log_info1 "Updated '$APP_NAME' plugin config"
}
fn-deploy-app() {
declare APP_NAME="$1"
verify_app_name "$APP_NAME"
local IMAGE;
IMAGE="$(get_app_image_name "$APP_NAME" latest)"
verify_image "$IMAGE" || return 1
release_and_deploy "$APP_NAME" "$IMAGE_TAG"
}
fn-install-plugin() {
declare APP_NAME="$1" PLUGIN_GIT_URL="$2"
fn-discourse-config-add-plugin "$APP_NAME" "$PLUGIN_GIT_URL"
local APP_STORAGE_ROOT="$STORAGE_ROOT/$APP_NAME"
fn-build-image "$APP_NAME" "$APP_STORAGE_ROOT"
}
fn-get-run-args() {
declare APP_NAME="$1"
"$DISCOURSE_DOCKER_IMAGE_ROOT"/launcher start-cmd "$CONTAINER_TYPE-$APP_NAME"
}
fn-upgrade-app() {
declare APP_NAME="$1"
fn-update-discourse-build-files
fn-build-image "$APP_NAME"
}
fn-get-env-vars-from-run-args() {
declare RUN_ARGS="$1"
# RUN_ARGS will be a string in form "+ true run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production" etc
# We want to extract the env vars from the string and produce a new string in form "ENV=var ENV2=var"
# 1. We use grep to extract the "-e ENV=var" strings
# 2. grep will give us newlines, so we convert those to spaces using tr
# 3. Next we use sed to remove "-e" flags as well as multiple consecutive whitespace chars
# 4. Finally we use sed to trim leading and trailing spaces
echo "$RUN_ARGS" | grep -Po '[[:space:]]-e[[:space:]]*[^[:space:]]+' | tr "\n" "\t" | sed -r "s/\s+\-e\s+|\s+/ /g" | sed -r 's/^\s*|\s*$//g'
}
fn-configure-app() {
declare APP_NAME="$1" HOSTNAME="$2" APP_STORAGE_ROOT="$3"
dokku_log_info1 "Generating docker config..."
local RUN_ARGS MAC_ADDRESS SHM_SIZE ENV_VARS
RUN_ARGS=$(fn-get-run-args "$APP_NAME" 2>&1 >/dev/null)
MAC_ADDRESS=$(echo "$RUN_ARGS" | sed -r 's/.*--mac-address(=| )([^ ]+).*/\2/')
SHM_SIZE=$(echo "$RUN_ARGS" | sed -r 's/.*--shm-size(=| )([^ ]+).*/\2/')
ENV_VARS=$(fn-get-env-vars-from-run-args "$RUN_ARGS")
domains_set "$APP_NAME" "$HOSTNAME"
## TODO: call plugin functions instead of dokku
dokku proxy:ports-add "$APP_NAME" http:80:80 # add correct port mapping
dokku proxy:ports-remove "$APP_NAME" http:80:5000 # remove default port mapping as a result of calling domains:set
# shellcheck disable=SC2086
config_set --no-restart "$APP_NAME" $ENV_VARS
## TODO: call plugin functions instead of dokku
! grep -q "$APP_STORAGE_ROOT:/shared" <<< "$(dokku storage:list "$APP_NAME" -q)" && \
dokku storage:mount "$APP_NAME" "$APP_STORAGE_ROOT:/shared"
! grep -q "$APP_STORAGE_ROOT/log/var-log:/var/log" <<< "$(dokku storage:list "$APP_NAME" -q)" && \
dokku storage:mount "$APP_NAME" "$APP_STORAGE_ROOT/log/var-log:/var/log"
## TODO: call plugin functions instead of dokku
dokku docker-options:add "$APP_NAME" run,deploy "--entrypoint /sbin/boot"
dokku docker-options:add "$APP_NAME" run,deploy "--hostname dokku-discourse"
dokku docker-options:add "$APP_NAME" run,deploy "--shm-size=$SHM_SIZE"
dokku docker-options:add "$APP_NAME" run,deploy "--mac-address $MAC_ADDRESS"
## TODO: call plugin functions instead of dokku
if fn-version-greater-equal "0.22.0"; then
dokku ps:set "$APP_NAME" restart-policy always
else
dokku ps:set-restart-policy "$APP_NAME" always
fi
}
fn-cleanup-app() {
declare APP_NAME="$1"
local CONTAINER_CONFIG="$DISCOURSE_DOCKER_IMAGE_ROOT/containers/$CONTAINER_TYPE-$APP_NAME.yml"
[[ -f "$CONTAINER_CONFIG" ]] && rm "$CONTAINER_CONFIG"
dokku_log_info1 "Cleaned up $APP_NAME config"
}
fn-destroy-app() {
declare APP_NAME="$1"
plugn trigger app-destroy "$APP_NAME"
sed -i "/^$APP_NAME$/d" "$DISCOURSE_APPS" 2> /dev/null
fn-cleanup-app "$APP_NAME"
}
fn-cleanup-plugin() {
[[ -f "$DISCOURSE_APPS" ]] && rm "$DISCOURSE_APPS"
[[ -d "$DISCOURSE_DOCKER_IMAGE_ROOT" ]] && rm -r "$DISCOURSE_DOCKER_IMAGE_ROOT"
dokku_log_info1 "Cleaned up $PLUGIN_COMMAND_PREFIX plugin"
}
fn-get-dokku-version() {
local DOKKU_LIB_ROOT=${DOKKU_LIB_PATH:="/var/lib/dokku"}
local DOKKU_VERSION
if [[ -f "$DOKKU_LIB_ROOT/STABLE_VERSION" ]]; then
DOKKU_VERSION=$(cat "${DOKKU_LIB_ROOT}/STABLE_VERSION")
elif [[ -f "$DOKKU_LIB_ROOT/VERSION" ]]; then
DOKKU_VERSION=$(cat "${DOKKU_LIB_ROOT}/VERSION")
fi
echo "$DOKKU_VERSION"
}
fn-discourse-help-content() {
cat <<help_content
${PLUGIN_COMMAND_PREFIX}:create <app>, Creates a new discourse app
${PLUGIN_COMMAND_PREFIX}:destroy <app>, Destroys a discourse app
${PLUGIN_COMMAND_PREFIX}:upgrade <app>, Upgrades a discourse app
${PLUGIN_COMMAND_PREFIX}:install-plugin <app> <git_url>, Installs a plugin for a discourse app
${PLUGIN_COMMAND_PREFIX}:list, Lists all discourse apps
help_content
}
cmd-discourse-help() {
if [[ $1 == "${PLUGIN_COMMAND_PREFIX}:help" ]]; then
echo -e "Usage: dokku ${PLUGIN_COMMAND_PREFIX}[:COMMAND] [<app>]"
echo ''
echo 'Manages discourse apps'
echo ''
echo 'Example:'
echo ''
echo "\$ dokku ${PLUGIN_COMMAND_PREFIX}:create app"
echo ''
echo 'Commands:'
fn-discourse-help-content | sort | column -c2 -t -s,
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
fn-discourse-help-content
else
cat <<help_desc
${PLUGIN_COMMAND_PREFIX}, Plugin for managing discourse apps
help_desc
fi
}