44# seeded data present, the updater able to replay the chain over it without
55# changing anything, and the site answering over HTTP.
66#
7- # Runs as the container entrypoint (see Dockerfile); every knob has a default
8- # so `docker run` with only EVO_DB_HOST set does something sensible.
7+ # Runs as the container entrypoint (see Dockerfile) and, in CI, directly on the
8+ # runner; every knob has a default so `docker run` with only EVO_DB_HOST set
9+ # does something sensible. EVO_DB_TYPE=sqlite needs no server at all.
10+ #
11+ # For the upgrade of an older release to this tree, see upgrade-and-smoke.sh.
912# pipefail: the installer output goes through tee, and a pipeline that hides
1013# the exit code of its first command would report a failed install as a pass.
1114set -euo pipefail
1215
1316APP_DIR=${EVO_APP_DIR:-/ var/ www/ html}
1417
15- EVO_DB_TYPE=${EVO_DB_TYPE:- mysql}
16- EVO_DB_HOST=${EVO_DB_HOST:- 127.0.0.1}
17- EVO_DB_USER=${EVO_DB_USER:- root}
18- EVO_DB_PASSWORD=${EVO_DB_PASSWORD:- secret}
19- EVO_DB_NAME=${EVO_DB_NAME:- evolution}
20- EVO_DB_PREFIX=${EVO_DB_PREFIX:- evo_}
18+ export EVO_DB_TYPE=${EVO_DB_TYPE:- mysql}
19+ export EVO_DB_HOST=${EVO_DB_HOST:- 127.0.0.1}
20+ export EVO_DB_USER=${EVO_DB_USER:- root}
21+ export EVO_DB_PASSWORD=${EVO_DB_PASSWORD:- secret}
22+ export EVO_DB_NAME=${EVO_DB_NAME:- evolution}
23+ export EVO_DB_PREFIX=${EVO_DB_PREFIX:- evo_}
2124
2225# Exported: smoke.php reads these to check what the installer stored.
2326export EVO_ADMIN=${EVO_ADMIN:- admin}
2427export EVO_ADMIN_EMAIL=${EVO_ADMIN_EMAIL:- admin@ evo.local}
2528export EVO_ADMIN_PASSWORD=${EVO_ADMIN_PASSWORD:- Passw0rd123}
2629export EVO_LANGUAGE=${EVO_LANGUAGE:- en}
2730
31+ # shellcheck source=lib.sh
32+ . " $( dirname " $0 " ) /lib.sh"
33+
2834LOG=/tmp/install.log
2935UPDATE_LOG=/tmp/update.log
30- PORT=${EVO_HTTP_PORT:- 8899}
31-
32- say () {
33- printf ' \n\033[1;36m== %s\033[0m\n' " $1 "
34- }
35-
36- fail () {
37- printf ' \033[1;31m!! %s\033[0m\n' " $1 " >&2
38- exit 1
39- }
40-
41- # Rejects a run that printed anything PHP or PDO would call a problem.
42- #
43- # php.ini in the image sends diagnostics to stdout and to stderr (see
44- # Dockerfile), and both are captured here, so a warning raised inside the output
45- # buffer the installer later discards still reaches this log.
46- #
47- # The patterns are anchored on how PHP formats a diagnostic ("Warning: text in
48- # /file on line N") rather than on the bare words, which turn up in plenty of
49- # legitimate output - the settings seeder alone writes rows whose names contain
50- # "error".
51- check_log () {
52- if grep -nE ' (^|PHP )(Warning|Notice|Deprecated|Fatal error|Parse error|Recoverable fatal error|Strict Standards):' " $1 " ; then
53- fail " the $2 emitted PHP diagnostics"
54- fi
55- # SQLSTATE is how both PDO drivers label a failed statement, and the
56- # installer swallows some of those into plain output instead of exiting.
57- if grep -nE ' SQLSTATE\[|Uncaught .*Exception|Migration not found|✖' " $1 " ; then
58- fail " the $2 reported a database or migration error"
59- fi
60- echo " no diagnostics in $( wc -l < " $1 " ) lines of $2 output"
61- }
6236
63- say " Waiting for ${EVO_DB_TYPE} at ${EVO_DB_HOST} "
64- # Compose already gates on a healthcheck, but this script is also meant to be
65- # runnable on its own against any reachable server.
66- attempt=0
67- until php -r '
68- $dsn = $argv[1] === "pgsql"
69- ? "pgsql:host=" . $argv[2] . ";dbname=" . $argv[5]
70- : "mysql:host=" . $argv[2];
71- new PDO($dsn, $argv[3], $argv[4]);
72- ' " $EVO_DB_TYPE " " $EVO_DB_HOST " " $EVO_DB_USER " " $EVO_DB_PASSWORD " " ${EVO_DB_BOOTSTRAP_NAME:- $EVO_DB_USER } " 2> /dev/null; do
73- attempt=$(( attempt + 1 ))
74- [ " $attempt " -lt 60 ] || fail " database never became reachable"
75- sleep 2
76- done
77- echo " reachable after ${attempt} attempt(s)"
37+ wait_for_db
7838
7939say " Installing Evolution CMS (${EVO_DB_TYPE} , database '${EVO_DB_NAME} ', prefix '${EVO_DB_PREFIX} ')"
8040# --skipComposer=y: core/vendor is committed, so there is nothing to install and
@@ -83,16 +43,12 @@ say "Installing Evolution CMS (${EVO_DB_TYPE}, database '${EVO_DB_NAME}', prefix
8343# sqlite leg of the build workflow already covers removal.
8444# Interactive prompts read from stdin; </dev/null makes an unanswered prompt an
8545# immediate failure instead of a hung job.
46+ mapfile -t db_args < <( installer_db_args)
8647cd " $APP_DIR /install"
8748set +e
8849php cli-install.php \
8950 --typeInstall=1 \
90- --databaseType=" $EVO_DB_TYPE " \
91- --databaseServer=" $EVO_DB_HOST " \
92- --database=" $EVO_DB_NAME " \
93- --databaseUser=" $EVO_DB_USER " \
94- --databasePassword=" $EVO_DB_PASSWORD " \
95- --tablePrefix=" $EVO_DB_PREFIX " \
51+ " ${db_args[@]} " \
9652 --cmsAdmin=" $EVO_ADMIN " \
9753 --cmsAdminEmail=" $EVO_ADMIN_EMAIL " \
9854 --cmsPassword=" $EVO_ADMIN_PASSWORD " \
@@ -140,55 +96,6 @@ say "Checking the data survived the update unchanged"
14096php " $APP_DIR /.github/docker/ci/smoke.php" " $APP_DIR " || fail " the update changed the installed data"
14197
14298say " Checking the installed site answers over HTTP"
143- php -S " 127.0.0.1:${PORT} " -t " $APP_DIR " > /tmp/server.log 2>&1 &
144- server=$!
145- trap ' kill "$server" 2>/dev/null || true' EXIT
146-
147- php -r '
148- // The front end and the manager are the two entry points an installed site
149- // has to serve. The manager answers 404 without an Accept-Language header
150- // by design, hence the header on the second request.
151- $port = $argv[1];
152- $get = function (string $path, array $headers = []) use ($port): array {
153- $context = stream_context_create(["http" => [
154- "ignore_errors" => true,
155- "timeout" => 20,
156- "header" => $headers,
157- ]]);
158- $body = @file_get_contents("http://127.0.0.1:{$port}{$path}", false, $context);
159- $status = isset($http_response_header[0]) ? (int) substr($http_response_header[0], 9, 3) : 0;
160- return [$status, (string) $body];
161- };
162-
163- for ($i = 0; $i < 30; $i++) {
164- [$status] = $get("/");
165- if ($status !== 0) {
166- break;
167- }
168- sleep(1);
169- }
170-
171- $failures = [];
172- [$status, $body] = $get("/");
173- echo "front page: {$status}\n";
174- $status === 200 or $failures[] = "the front page answered {$status}";
175- // The seeded document, rendered through the seeded template - proof the
176- // CMS read its own data rather than merely booting.
177- str_contains($body, "Install Successful!") or $failures[] = "the front page did not render the seeded document";
178-
179- [$status, $body] = $get("/manager/index.php", ["Accept-Language: en-US,en;q=0.9"]);
180- echo "manager: {$status}\n";
181- $status === 200 or $failures[] = "the manager answered {$status}";
182- stripos($body, "password") !== false or $failures[] = "the manager did not render its login form";
183-
184- if ($failures !== []) {
185- fwrite(STDERR, " - " . implode("\n - ", $failures) . "\n");
186- exit(1);
187- }
188- echo "both entry points served the installed site\n";
189- ' " $PORT " || {
190- tail -40 /tmp/server.log >&2
191- fail " the installed site did not answer correctly"
192- }
99+ http_check " $APP_DIR "
193100
194101say " OK: ${EVO_DB_TYPE} installation is clean, migrated and seeded"
0 commit comments