forked from BlueprintFramework/framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
blueprint.sh
336 lines (288 loc) · 15.5 KB
/
blueprint.sh
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
# © 2023-2024 Ivy (prpl.wtf)
# Learn more @ blueprint.zip
# Source code available at github.com/blueprintframework/framework
# Variable for telling Blueprint which folder Pterodactyl lives in.
FOLDER=$(realpath "$(dirname "$0")")
# This stores the webserver ownership user which Blueprint uses when applying webserver permissions.
OWNERSHIP="www-data:www-data" #;
# This stores options for permissions related to running install scripts the webserver user.
WEBUSER="www-data" #;
USERSHELL="/bin/bash" #;
# Defines the version Blueprint will display as the active one.
VERSION="beta-2024-08"
# Default GitHub repository to use when upgrading Blueprint.
REPOSITORY="BlueprintFramework/framework"
# Set environment variables.
export BLUEPRINT__FOLDER=$FOLDER
export BLUEPRINT__VERSION=$VERSION
export BLUEPRINT__DEBUG="$FOLDER"/.blueprint/extensions/blueprint/private/debug/logs.txt
export NODE_OPTIONS=--openssl-legacy-provider
# Check if the script is being sourced - and if so - load bash autocompletion.
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
_blueprint_completions() {
local cur cmd opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
cmd="${COMP_WORDS[1]}"
case "${cmd}" in
-install|-add|-i) opts="$(find "$BLUEPRINT__SOURCEFOLDER"/*.blueprint | sed -e "s|^$BLUEPRINT__SOURCEFOLDER/||g" -e "s|.blueprint$||g")" ;;
-remove|-r) opts="$(sed "s|,||g" "$BLUEPRINT__SOURCEFOLDER/.blueprint/extensions/blueprint/private/db/installed_extensions")" ;;
-export) opts="expose" ;;
-debug) opts="100 200" ;;
-upgrade) opts="remote" ;;
*) opts="-install -add -remove -init -build -export -wipe -version -help -info -debug -upgrade -rerun-install" ;;
esac
if [[ ${cur} == * ]]; then
# shellcheck disable=SC2207
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
}
complete -F _blueprint_completions blueprint
return 0
fi
# Check for panels that are using Docker, which should have better support in the future.
if [[ -f "/.dockerenv" ]]; then
DOCKER="y"
FOLDER="/app"
else
DOCKER="n"
fi
# This has caused a bunch of errors but is just here to make sure people actually upload the
# "blueprint" folder onto their panel when installing Blueprint. Pick your poison.
if [[ -d "$FOLDER/blueprint" ]]; then mv "$FOLDER/blueprint" "$FOLDER/.blueprint"; fi
if [[ $VERSION != "" ]]; then
# This function makes sure some placeholders get replaced with the current Blueprint version.
if [[ ! -f "$FOLDER/.blueprint/extensions/blueprint/private/db/version" ]]; then
sed -E -i "s*::v*$VERSION*g" "$FOLDER/app/BlueprintFramework/Services/PlaceholderService/BlueprintPlaceholderService.php"
sed -E -i "s*::v*$VERSION*g" "$FOLDER/.blueprint/extensions/blueprint/public/index.html"
touch "$FOLDER/.blueprint/extensions/blueprint/private/db/version"
fi
fi
# Set internal variables.
__BuildDir=".blueprint/extensions/blueprint/private/build"
# Automatically navigate to the Pterodactyl directory when running the script.
cd "$FOLDER" || return
# Import libraries.
source scripts/libraries/parse_yaml.sh || missinglibs+="[parse_yaml]"
source scripts/libraries/grabenv.sh || missinglibs+="[grabenv]"
source scripts/libraries/logFormat.sh || missinglibs+="[logFormat]"
source scripts/libraries/misc.sh || missinglibs+="[misc]"
source scripts/libraries/configutility.sh || missinglibs+="[configutility]"
# -config
# usage: "cITEM=VALUE bash blueprint.sh -config"
if [[ "$1" == "-config" ]]; then ConfigUtility; fi
cdhalt() { PRINT FATAL "Attempted navigation into nonexistent directory, halting process."; exit 1; }
depend() {
# Check for compatible node versions
nodeVer=$(node -v)
if [[ $nodeVer != "v17."* ]] \
&& [[ $nodeVer != "v18."* ]] \
&& [[ $nodeVer != "v19."* ]] \
&& [[ $nodeVer != "v20."* ]] \
&& [[ $nodeVer != "v21."* ]] \
&& [[ $nodeVer != "v22."* ]]; then
DEPEND_MISSING=true
fi
# Check for required (both internal and external) dependencies.
if \
! [ -x "$(command -v unzip)" ] || # unzip
! [ -x "$(command -v node)" ] || # node
! [ -x "$(command -v yarn)" ] || # yarn
! [ -x "$(command -v zip)" ] || # zip
! [ -x "$(command -v curl)" ] || # curl
! [ -x "$(command -v php)" ] || # php
! [ -x "$(command -v git)" ] || # git
! [ -x "$(command -v grep)" ] || # grep
! [ -x "$(command -v sed)" ] || # sed
! [ -x "$(command -v awk)" ] || # awk
! [ -x "$(command -v tput)" ] || # tput
! [ "$(ls "node_modules/"*"cross-env"* 2> /dev/null)" ] || # cross-env
! [ "$(ls "node_modules/"*"webpack"* 2> /dev/null)" ] || # webpack
! [ "$(ls "node_modules/"*"react"* 2> /dev/null)" ] || # react
[[ $missinglibs != "" ]]; then # internal
DEPEND_MISSING=true
fi
# Exit when missing dependencies.
if [[ $DEPEND_MISSING == true ]]; then
PRINT FATAL "Some framework dependencies are not installed or detected."
if [[ $nodeVer != "v18."* ]] \
&& [[ $nodeVer != "v19."* ]] \
&& [[ $nodeVer != "v20."* ]] \
&& [[ $nodeVer != "v21."* ]] \
&& [[ $nodeVer != "v22."* ]]; then
PRINT FATAL "Required dependency \"node\" is using an unsupported version."
fi
if ! [ -x "$(command -v unzip)" ]; then PRINT FATAL "Required dependency \"unzip\" is not installed or detected."; fi
if ! [ -x "$(command -v node)" ]; then PRINT FATAL "Required dependency \"node\" is not installed or detected."; fi
if ! [ -x "$(command -v yarn)" ]; then PRINT FATAL "Required dependency \"yarn\" is not installed or detected."; fi
if ! [ -x "$(command -v zip)" ]; then PRINT FATAL "Required dependency \"zip\" is not installed or detected."; fi
if ! [ -x "$(command -v curl)" ]; then PRINT FATAL "Required dependency \"curl\" is not installed or detected."; fi
if ! [ -x "$(command -v php)" ]; then PRINT FATAL "Required dependency \"php\" is not installed or detected."; fi
if ! [ -x "$(command -v git)" ]; then PRINT FATAL "Required dependency \"git\" is not installed or detected."; fi
if ! [ -x "$(command -v grep)" ]; then PRINT FATAL "Required dependency \"grep\" is not installed or detected."; fi
if ! [ -x "$(command -v sed)" ]; then PRINT FATAL "Required dependency \"sed\" is not installed or detected."; fi
if ! [ -x "$(command -v awk)" ]; then PRINT FATAL "Required dependency \"awk\" is not installed or detected."; fi
if ! [ -x "$(command -v tput)" ]; then PRINT FATAL "Required dependency \"tput\" is not installed or detected."; fi
if ! [ "$(ls "node_modules/"*"cross-env"* 2> /dev/null)" ]; then PRINT FATAL "Required dependency \"cross-env\" is not installed or detected."; fi
if ! [ "$(ls "node_modules/"*"webpack"* 2> /dev/null)" ]; then PRINT FATAL "Required dependency \"webpack\" is not installed or detected."; fi
if ! [ "$(ls "node_modules/"*"react"* 2> /dev/null)" ]; then PRINT FATAL "Required dependency \"react\" is not installed or detected."; fi
if [[ $missinglibs == *"[parse_yaml]"* ]]; then PRINT FATAL "Required internal dependency \"internal:parse_yaml\" is not installed or detected."; fi
if [[ $missinglibs == *"[grabEnv]"* ]]; then PRINT FATAL "Required internal dependency \"internal:grabEnv\" is not installed or detected."; fi
if [[ $missinglibs == *"[logFormat]"* ]]; then PRINT FATAL "Required internal dependency \"internal:logFormat\" is not installed or detected."; fi
if [[ $missinglibs == *"[misc]"* ]]; then PRINT FATAL "Required internal dependency \"internal:misc\" is not installed or detected."; fi
if [[ $missinglibs == *"[configutility]"* ]]; then PRINT FATAL "Required internal dependency \"internal:configutility\" is not installed or detected."; fi
exit 1
fi
}
# Assign variables for extension flags.
assignflags() {
F_ignorePlaceholders=false
F_forceLegacyPlaceholders=false
F_hasInstallScript=false
F_hasRemovalScript=false
F_hasExportScript=false
F_developerIgnoreInstallScript=false
F_developerIgnoreRebuild=false
F_developerForceMigrate=false
F_developerKeepApplicationCache=false
F_developerEscalateExportScript=false
if [[ ( $flags == *"ignorePlaceholders,"* ) || ( $flags == *"ignorePlaceholders" ) ]]; then F_ignorePlaceholders=true ;fi
if [[ ( $flags == *"forceLegacyPlaceholders,"* ) || ( $flags == *"forceLegacyPlaceholders" ) ]]; then F_forceLegacyPlaceholders=true ;fi
if [[ ( $flags == *"hasInstallScript,"* ) || ( $flags == *"hasInstallScript" ) ]]; then F_hasInstallScript=true ;fi
if [[ ( $flags == *"hasRemovalScript,"* ) || ( $flags == *"hasRemovalScript" ) ]]; then F_hasRemovalScript=true ;fi
if [[ ( $flags == *"hasExportScript,"* ) || ( $flags == *"hasExportScript" ) ]]; then F_hasExportScript=true ;fi
if [[ ( $flags == *"developerIgnoreInstallScript,"* ) || ( $flags == *"developerIgnoreInstallScript" ) ]]; then F_developerIgnoreInstallScript=true ;fi
if [[ ( $flags == *"developerIgnoreRebuild,"* ) || ( $flags == *"developerIgnoreRebuild" ) ]]; then F_developerIgnoreRebuild=true ;fi
if [[ ( $flags == *"developerForceMigrate,"* ) || ( $flags == *"developerForceMigrate" ) ]]; then F_developerForceMigrate=true ;fi
if [[ ( $flags == *"developerKeepApplicationCache,"* ) || ( $flags == *"developerKeepApplicationCache" ) ]]; then F_developerKeepApplicationCache=true ;fi
if [[ ( $flags == *"developerEscalateExportScript,"* ) || ( $flags == *"developerEscalateExportScript" ) ]]; then F_developerEscalateExportScript=true ;fi
}
# Adds the "blueprint" command to the /usr/local/bin directory and configures the correct permissions for it.
placeshortcut() {
PRINT INFO "Placing Blueprint command shortcut.."
{
touch /usr/local/bin/blueprint
chmod u+x \
"$FOLDER/blueprint.sh" \
/usr/local/bin/blueprint
} >> "$BLUEPRINT__DEBUG"
echo -e \
"#!/bin/bash \n" \
"if [[ \"\${BASH_SOURCE[0]}\" != \"\${0}\" ]]; then export BLUEPRINT__SOURCEFOLDER=\"$FOLDER\"; source \"$FOLDER/blueprint.sh\"; return 0; fi; "\
"bash $FOLDER/blueprint.sh -bash \$@;" \
> /usr/local/bin/blueprint
}
if ! [ -x "$(command -v blueprint)" ]; then placeshortcut; fi
if [[ $1 != "-bash" ]]; then
if dbValidate "blueprint.setupFinished"; then
PRINT FATAL "Installation process has already been finished before, consider using the 'blueprint' command."
exit 2
else
# Only run if Blueprint is not in the process of upgrading.
if [[ $1 != "--post-upgrade" ]]; then
# Print Blueprint icon with ascii characters.
C0="\x1b[0m"
C1="\x1b[31;43;1m"
C2="\x1b[32;44;1m"
C3="\x1b[34;45;1m"
C3="\x1b[0;37;1m"
echo -e "$C0" \
"\n$C4 ██$C1▌$C2▌$C3▌$C0 Blueprint Framework" \
"\n$C4██ ██$C1▌$C2▌$C3▌$C0 https://blueprint.zip" \
"\n$C4 ████$C1▌$C2▌$C3▌$C0 © 2023-2024 Ivy (prpl.wtf)\n";
fi
PRINT INFO "Searching and validating framework dependencies.."
depend # Check if required dependencies are installed
placeshortcut # Place Blueprint shortcut
# Link directories.
PRINT INFO "Linking directories and filesystems.."
{
ln -s -r -T "$FOLDER/.blueprint/extensions/blueprint/public" "$FOLDER/public/extensions/blueprint"
ln -s -r -T "$FOLDER/.blueprint/extensions/blueprint/assets" "$FOLDER/public/assets/extensions/blueprint"
ln -s -r -T "$FOLDER/scripts/libraries" "$FOLDER/.blueprint/lib"
} 2>> "$BLUEPRINT__DEBUG"
php artisan storage:link &>> "$BLUEPRINT__DEBUG"
# Copy "Blueprint" extension page logo from assets.
cp "$FOLDER/.blueprint/assets/Emblem/emblem.jpg" "$FOLDER/.blueprint/extensions/blueprint/assets/logo.jpg"
# Put application into maintenance.
PRINT INPUT "Would you like to put your application into maintenance while Blueprint is installing? (Y/n)"
read -r YN
if [[ ( $YN == "y"* ) || ( $YN == "Y"* ) || ( $YN == "" ) ]]; then
MAINTENANCE="true"
PRINT INFO "Put application into maintenance mode."
php artisan down &>> "$BLUEPRINT__DEBUG"
else
MAINTENANCE="false"
PRINT INFO "Putting application into maintenance has been skipped."
fi
# Flush cache.
PRINT INFO "Flushing view, config and route cache.."
{
php artisan view:cache
php artisan config:cache
php artisan route:clear
php artisan cache:clear
php artisan bp:cache
} &>> "$BLUEPRINT__DEBUG"
# Run migrations if Blueprint is not upgrading.
if [[ ( $1 != "--post-upgrade" ) && ( $DOCKER != "y" ) ]]; then
PRINT INPUT "Would you like to migrate your database? (Y/n)"
read -r YN
if [[ ( $YN == "y"* ) || ( $YN == "Y"* ) || ( $YN == "" ) ]]; then
PRINT INFO "Running database migrations.."
php artisan migrate --force
else
PRINT INFO "Database migrations have been skipped."
fi
fi
# Make sure all files have correct permissions.
PRINT INFO "Changing Pterodactyl file ownership to '$OWNERSHIP'.."
find "$FOLDER/" \
-path "$FOLDER/node_modules" -prune \
-o -exec chown "$OWNERSHIP" {} + &>> "$BLUEPRINT__DEBUG"
# Rebuild panel assets.
PRINT INFO "Rebuilding panel assets.."
yarn run build:production --progress
if [[ $DOCKER != "y" ]]; then
# Sync some database values.
PRINT INFO "Syncing Blueprint-related database values.."
php artisan bp:sync
fi
if [[ $DOCKER != "y" ]] && [[ $MAINTENANCE == "true" ]]; then
# Put application into production.
PRINT INFO "Put application into production."
php artisan up &>> "$BLUEPRINT__DEBUG"
fi
# Finish installation
if [[ $1 != "--post-upgrade" ]]; then
PRINT SUCCESS "Blueprint has completed its installation process."
fi
dbAdd "blueprint.setupFinished"
# Let the panel know the user has finished installation.
sed -i "s~NOTINSTALLED~INSTALLED~g" "$FOLDER/app/BlueprintFramework/Services/PlaceholderService/BlueprintPlaceholderService.php"
exit 0
fi
fi
Command() {
PRINT FATAL "'$cmd' is not a valid command or argument. Use argument '-help' for a list of commands."
}
cmd="${2}"
case "$cmd" in
-add|-install|-i) source ./scripts/commands/extensions/install.sh ;;
-remove|-r) source ./scripts/commands/extensions/remove.sh ;;
-init|-I) source ./scripts/commands/developer/init.sh ;;
-build|-b) source ./scripts/commands/developer/build.sh ;;
-wipe|-w) source ./scripts/commands/developer/wipe.sh ;;
-export|-e) source ./scripts/commands/developer/export.sh ;;
-info|-f) source ./scripts/commands/misc/info.sh ;;
-debug) source ./scripts/commands/misc/debug.sh ;;
-help|-h|help|'') source ./scripts/commands/misc/help.sh ;;
-version|-v) source ./scripts/commands/misc/version.sh ;;
-rerun-install) source ./scripts/commands/advanced/rerun-install.sh ;;
-upgrade) source ./scripts/commands/advanced/upgrade.sh ;;
esac
shift 2
Command "$*"
exit 0