From c4e09fa1836a857e840ecd5d2aa9181ff21d6d2d Mon Sep 17 00:00:00 2001 From: derek-henderson-K1 <140744865+derek-henderson-K1@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:19:47 -0400 Subject: [PATCH 01/27] Mecontract 240 (#2) * MECONTRACK-240 - Script integration * MECONTRACK-240 - php.ini feature * MECONTRACK-240 - Docker shell script * MECONTRACT-240 - Docker startup script for Moodle. * MECONTRACT-240 - Update with to add error checking on switches. * MECONTRACT-240 - Add in check Moodle version to update PHP version * MECONTRACT-240 - Remove extra file. * MECONTRACT-240 - Remove extra file. * MECONTRACT-240 - Update the code to choose the php version better. * MECONTRACT-240 - Code improvements: - remove moodle.ini from base.yml; - ensure that when no options entered default option of build is used; - when re-booting just start and restart the site; - add in checks to see if containers are started / not started and provide error messages. --- assets/adminer/plugins/001-tables-filter.php | 4 + assets/adminer/plugins/002-readable-dates.php | 4 + .../plugins/003-table-header-scroll.php | 4 + .../plugins/004-pretty-json-column.php | 4 + assets/adminer/plugins/pretty-json-column.php | 40 ++++ assets/adminer/plugins/readable-dates.php | 49 +++++ .../adminer/plugins/table-header-scroll.php | 75 +++++++ assets/php/10-docker-php-moodle.ini | 13 ++ k1run.sh | 196 ++++++++++++++++++ local.yml | 31 +++ local.yml_many | 18 ++ local.yml_single | 31 +++ 12 files changed, 469 insertions(+) create mode 100644 assets/adminer/plugins/001-tables-filter.php create mode 100644 assets/adminer/plugins/002-readable-dates.php create mode 100644 assets/adminer/plugins/003-table-header-scroll.php create mode 100644 assets/adminer/plugins/004-pretty-json-column.php create mode 100644 assets/adminer/plugins/pretty-json-column.php create mode 100644 assets/adminer/plugins/readable-dates.php create mode 100644 assets/adminer/plugins/table-header-scroll.php create mode 100644 assets/php/10-docker-php-moodle.ini create mode 100644 k1run.sh create mode 100644 local.yml create mode 100644 local.yml_many create mode 100644 local.yml_single diff --git a/assets/adminer/plugins/001-tables-filter.php b/assets/adminer/plugins/001-tables-filter.php new file mode 100644 index 00000000000..c2265a32e97 --- /dev/null +++ b/assets/adminer/plugins/001-tables-filter.php @@ -0,0 +1,4 @@ +adminer = $adminer; + } + + private function _testJson($value) { + if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) { + return $json; + } + return $value; + } + + function editInput($table, $field, $attrs, $value) { + $json = $this->_testJson($value); + if ($json !== $value) { + $jsonText = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + return <<$jsonText +HTML; + } + return ''; + } + + function processInput($field, $value, $function = '') { + if ($function === '') { + $json = $this->_testJson($value); + if ($json !== $value) { + $value = json_encode($json); + } + } + return $this->adminer->_callParent('processInput', array($field, $value, $function)); + } +} diff --git a/assets/adminer/plugins/readable-dates.php b/assets/adminer/plugins/readable-dates.php new file mode 100644 index 00000000000..d9ca75ac16d --- /dev/null +++ b/assets/adminer/plugins/readable-dates.php @@ -0,0 +1,49 @@ +prepend = <<'; + tds[i].innerHTML = tds[i].newDate; + tds[i].dateIsNew = true; + + tds[i].addEventListener('click', function(event) { + this.innerHTML = (this.dateIsNew ? this.oldDate : this.newDate); + this.dateIsNew = !this.dateIsNew; + }); + } + } +}); + +EOT; + } + + function head() { + echo script($this->prepend); + } +} diff --git a/assets/adminer/plugins/table-header-scroll.php b/assets/adminer/plugins/table-header-scroll.php new file mode 100644 index 00000000000..69eace5c3ac --- /dev/null +++ b/assets/adminer/plugins/table-header-scroll.php @@ -0,0 +1,75 @@ +. + * + * LICENSE: + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class AdminerTableHeaderScroll +{ + public function head() + { + ?> + +> +function tableHeaderPositionUpdate(){ + // If your theme has a fixed position header, change these for compatibility + var offset = -1; + var zindex = 10000; + + // Find tables in the content + var tables = document.getElementById('content').getElementsByTagName('table'); + for (var i = 0; i < tables.length; i++) { + var table = tables[i]; + + // Find the table header + var tableHeader = table.getElementsByTagName('thead'); + if (tableHeader.length) { + tableHeader = tableHeader[0]; + } else { + continue; + } + + // Calculate the distance from the top and bottom + var tableTop = table.getBoundingClientRect().top - offset; + var tableBottom = table.getBoundingClientRect().bottom - offset - tableHeader.offsetHeight; + + // Set the relative position based on the distance + if (tableTop < 0 && tableBottom > 0){ + tableHeader.style['z-index'] = zindex; + tableHeader.style.position = 'relative'; + + if (typeof tableHeader.style.transform === 'undefined') { + tableHeader.style.top = -tableTop + 'px'; + } else { + tableHeader.style.transform = 'translateY(' + -tableTop + 'px)'; + } + } else { + tableHeader.style.position = 'static'; + tableHeader.style.transform = 'none'; + } + } +} + +if (window.addEventListener) { + window.addEventListener('scroll', tableHeaderPositionUpdate); +} + + + Date: Tue, 29 Oct 2024 10:49:05 -0400 Subject: [PATCH 02/27] MECONTRACT-242 - Add in multiple site script (#4) * MECONTRACT-242 - Add in multiple site script * MECONTRACT-242 - Add in options and examples. - Add in options for start, stop, restart. Improved help to give examokes. * MECONTRACK-242 - Modify help message to match script functionality. * MECONTRACK-242 - If no args is passed the script display the help message. This is done way before reaching the removed code. * MECONTRACK-242 - Use exit instead of return. * MECONTRACK-242 - Fancy error messages. * MECONTRACK-242 - Only start the containers if they are not running when using --phpunit. * MECONTRACK-242 - No need to copy the Adminer plugin again when using --phpunit. * MECONTRACK-242 - Only start the containers if they are not running when using --behat. * MECONTRACK-242 - Copy the Adminer plugins after --reboot. * MECONTRACT-242 - Streamline code. - ensure the arguments passed in are checked properly; - ensure exit commands are used rather than returns; - group commands to reduce redundancy; --- k1many.sh | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ k1run.sh | 85 ++++++++++++++----------- 2 files changed, 232 insertions(+), 35 deletions(-) create mode 100644 k1many.sh diff --git a/k1many.sh b/k1many.sh new file mode 100644 index 00000000000..ac9c0d77b7f --- /dev/null +++ b/k1many.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +help_messages () { + echo "Usage: sh k1many.sh [option] [folder1] [folder2] [folder2]" + echo "Script that can start multiple sites." + echo + echo "--build Start the site and initialize the sites." + echo "--destroy Stop the sites. Destroy all data" + echo "--help display this message" + echo "--restart Restart all running sites." + echo "--start Start all stopped sites." + echo "--stop Stop all running sites." + + echo "{folder1} -folder pointing to first Moodle site (Mandatory)" + echo "{folder2} -folder pointing to second Moodle site (optional)" + echo "{folder3} -folder pointing to third Moodle site (optional)" + echo " + Examples: + sh k1many.sh --build M405 # Start a site with the folder in docker/M405 folder + sh k1many.sh --build M405 M401 MT # Start three sites with based in docker/M405, docker/M401, docker/MT + sh k1many.sh --start # Start all stopped sites + sh k1many.sh --stop # Stop all stopped sites + sh k1many.sh --destroy # Stop and destroy sites + " +} + +start_server() { + # Start the server + bin/moodle-docker-compose up -d + # Sleep for 6 seconds to allow database to come up + sleep 6 + # Just in case there is still some latency. + bin/moodle-docker-wait-for-db + return 0 +} + +exists_in_list() { + LIST=$1 + DELIMITER=$2 + VALUE=$3 + LIST_WHITESPACES=`echo $LIST | tr "$DELIMITER" " "` + for x in $LIST_WHITESPACES; do + if [ "$x" = "$VALUE" ]; then + return 1 + fi + done + return 0 +} + +# Variables +# MOODLE_DOCKER_DB - database used by Moodle - default maria db +# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located; +# MOODLE_DOCKER_PORT - port (default 8000); +# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1; +# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites; + +if [ $# -eq 0 ]; then + echo "No arguments supplied" + help_messages + exit 1 +fi + +if [ $# -lt 1 ] || [ $# -gt 4 ] ; then + echo "Invalid number of arguments passed in. Must be between 1 and 4 arguments" + help_messages + exit 1 +fi + +ist_of_options="--build --destroy --help --reboot --stop --start --restart" +cwd=$( dirname "$PWD" ) +count=0 +for var in "$@" +do + count=$((count+1)) + if [ "$count" -eq 1 ]; then + SWITCH=${var} + # Check to see if the list of arguments is valid. + if exists_in_list "$list_of_options" " " $SWITCH; then + echo "Invalid option $SWITCH" + help_messages + exit 1 + fi + # Check for any swithes that don't need options. + case $SWITCH in + "--build") + if [ -n "$(docker ps -f "name=site1-webserver-1" -f "status=running" -q )" ]; then + echo "The first site is already running!. It cannot be re-initialized." + exit 1 + fi + # Do the basics to start the site. + export MOODLE_DOCKER_DB=mariadb + export COMPOSE_PROJECT_NAME=site1 + cp local.yml_many local.yml + ;; + "--help") + help_messages + exit 1 + ;; + "--destroy") + if ! docker ps | grep -q 'moodlehq'; then + echo "No containers running. Nothing to shutdown" + exit 1 + fi + docker stop $(docker ps -a -q) + docker rm $(docker ps -a -q) + echo "All containers shut down and removed." + exit 1 + ;; + # Restart + "--restart") + if ! docker ps | grep -q 'moodlehq'; then + echo "No containers running. Nothing to reboot" + exit 1 + fi + docker restart $(docker ps -q) + echo "All sites restarted" + exit 1 + ;; + # Start + "--start") + if [ -n "$(docker ps -f "name=site1-webserver-1" -f "status=running" -q )" ]; then + echo "Sites are already running." + exit 1 + fi + docker start $(docker ps -a -q -f status=exited) + echo "All sites started" + exit 1 + ;; + # Stop + "--stop") + if ! docker ps | grep -q 'moodlehq'; then + echo "No containers running. Nothing to stop" + exit 1 + fi + docker stop $(docker ps -q) + echo "All sites stopped" + exit 1 + ;; + + esac + else + folder="${cwd}/${var}" + if [ ! -d "${folder}" ]; then + echo "${folder} is not valid" + exit 1 + fi + # Start the site + # Check the Moodle version. If its 4.5 then set php version to 8.3 + export MOODLE_DOCKER_PHP_VERSION=8.1 + moodlever=$(grep "$branch = '405';" $folder/version.php) + if [ "$moodlever" ]; then + export MOODLE_DOCKER_PHP_VERSION=8.3 + fi + export MOODLE_DOCKER_WWWROOT=${folder} + cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php + case $count in + "2") + export COMPOSE_PROJECT_NAME=site1 + export MOODLE_DOCKER_WEB_PORT=8000 + start_server + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site1" --shortname="site1" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" + echo "${folder} site started - port 8000" + ;; + "3") + export COMPOSE_PROJECT_NAME=site2 + export MOODLE_DOCKER_WEB_PORT=1234 + start_server + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site2" --shortname="site1" --summary="Site 2" --adminpass="test" --adminemail="admin@example.com" + echo "${folder} site started - port 1234" + ;; + "4") + export COMPOSE_PROJECT_NAME=site3 + export MOODLE_DOCKER_WEB_PORT=6789 + start_server + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site3" --shortname="site3" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" + echo "${folder} site started - port 6789" + ;; + esac + fi +done + +return diff --git a/k1run.sh b/k1run.sh index 68627e369a8..1018f08d1a2 100644 --- a/k1run.sh +++ b/k1run.sh @@ -4,19 +4,30 @@ adminer_plugins () { # Add in Adminer plugins docker cp assets/adminer/plugins/readable-dates.php docker-Adminer:/var/www/html/plugins/readable-dates.php docker cp assets/adminer/plugins/table-header-scroll.php docker-Adminer:/var/www/html/plugins/table-header-scroll.php - docker cp assets/adminer/plugins/pretty-json-column.php docker-Adminer:/var/www/html/plugins/pretty-json-column.php + docker cp assets/adminer/plugins/pretty-json-column.php docker-Adminer:/var/www/html/plugins/pretty-json-column.php docker cp assets/adminer/plugins/002-readable-dates.php docker-Adminer:/var/www/html/plugins-enabled/002-readable-dates.php docker cp assets/adminer/plugins/003-table-header-scroll.php docker-Adminer:/var/www/html/plugins-enabled/003-table-header-scroll.php docker cp assets/adminer/plugins/004-pretty-json-column.php docker-Adminer:/var/www/html/plugins-enabled/004-pretty-json-column.php } +error_message() { + RED='\033[0;31m' + NC='\033[0m' # No Color + echo + echo "${RED}$1${NC}" + echo +} + help_messages () { + echo + echo "Script that automates managing docker." + echo echo "Usage: sh k1run.sh [folder] [option] [option2]" - echo "Script that automate managing docker." echo - echo "If no parameter is passed then boot and initialize the site." + echo "If no parameter is passed then display this help message." echo echo "--build Start the site and initialize the site." + echo "--build --phpunit|--behat Start the containers, install Moodle then initialize Behat or PHPUnit" echo "--down Stop the site. Keep data" echo "--destroy Stop the site, destory data" echo "--reboot Restart the site - destroy all containers and re-initialize" @@ -39,17 +50,16 @@ exists_in_list() { } if [ $# -eq 0 ]; then - echo "No arguments supplied" help_messages - return + exit 1 fi #Count the variables passed in. variablecount=$# if [ $# -lt 1 ] || [ $# -gt 3 ] ; then - echo "Invalid number of arguments passed in. Must be between 1 and 3 arguments" + error_message "Invalid number of arguments passed in. Must be between 1 and 3 arguments" help_messages - return + exit 1 fi cwd=$( dirname "$PWD" ) @@ -58,8 +68,9 @@ folder="${1}" folder="${cwd}/${folder}" if [ ! -d "${folder}" ]; then - echo "${folder} is not valid" - return + error_message "${folder} is not valid" + help_messages + exit 1 fi SWITCH=$2 @@ -72,31 +83,26 @@ SWITCH2=$3 if [ "$SWITCH" = "--help" ]; then help_messages -fi - -# if no variable passed in then build the site. -if [ -z "$SWITCH" ]; then - SWITCH='--build' + exit 1 fi list_of_options="--build --down --destroy --reboot --load --phpunit --behat" if exists_in_list "$list_of_options" " " $SWITCH; then - echo "Invalid option $SWITCH" + error_message "Invalid option $SWITCH" help_messages - return + exit 1 fi if [ "$variablecount" -eq 3 ]; then if exists_in_list "$list_of_options" " " $SWITCH2; then - echo "Invalid option $SWITCH2" + error_message "Invalid option $SWITCH2" help_messages - return + exit 1 fi fi # Always use mariadb as a database. - export MOODLE_DOCKER_DB=mariadb export MOODLE_DOCKER_WWWROOT=${folder} @@ -114,8 +120,9 @@ cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php if [ "$SWITCH" = "--build" ]; then # Check to see if the docker containers are running. if [ -n "$(docker ps -f "name=docker-webserver-1" -f "status=running" -q )" ]; then - echo "The Webserver is already running!. It cannot be re-initialized." - return; + error_message "The Webserver is already running!. It cannot be re-initialized." + help_messages + exit 1 fi # Start up containers bin/moodle-docker-compose up -d @@ -137,7 +144,7 @@ fi # DESTROY if [ "$SWITCH" = "--destroy" ]; then if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to shutdown" + error_message "No containers running. Nothing to shutdown" exit 1 fi bin/moodle-docker-compose down @@ -145,20 +152,27 @@ fi # PNPUNIT ONLY if [ "$SWITCH" = "--phpunit" ]; then - # Start up containers - bin/moodle-docker-compose up -d - # Wait for DB to come up - bin/moodle-docker-wait-for-db - bin/moodle-docker-compose exec webserver php admin/tool/phpunit/cli/init.php - adminer_plugins + # Only start the containers if they are not running. + if ! docker ps | grep -q 'moodlehq'; then + # Start up containers + bin/moodle-docker-compose up -d + # Wait for DB to come up + bin/moodle-docker-wait-for-db + adminer_plugins + fi + bin/moodle-docker-compose exec webserver php admin/tool/phpunit/cli/init.php fi # BEHAT ONLY if [ "$SWITCH" = "--behat" ]; then - # Start up containers - bin/moodle-docker-compose up -d - # Wait for DB to come up - bin/moodle-docker-wait-for-db + # Only start the containers if they are not running. + if ! docker ps | grep -q 'moodlehq'; then + # Start up containers + bin/moodle-docker-compose up -d + # Wait for DB to come up + bin/moodle-docker-wait-for-db + adminer_plugins + fi bin/moodle-docker-compose exec webserver php admin/tool/behat/cli/init.php fi @@ -166,20 +180,21 @@ fi if [ "$SWITCH" = "--reboot" ]; then # Stop the containers if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to reboot" + error_message "No containers running. Nothing to reboot" exit 1 fi bin/moodle-docker-compose stop sleep 3 # Re-start up containers bin/moodle-docker-compose start + adminer_plugins fi # DOWN if [ "$SWITCH" = "--down" ]; then # Check to see if containers are running. if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to shutdown" + error_message "No containers running. Nothing to shutdown" exit 1 fi # Stop the containers @@ -193,4 +208,4 @@ if [ "$SWITCH" = "--load" ]; then adminer_plugins fi -return +exit 0 From 3b316c89e02f5e0f96eb778982a6b84886e7f7e1 Mon Sep 17 00:00:00 2001 From: derek-henderson-K1 <140744865+derek-henderson-K1@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:13:26 -0500 Subject: [PATCH 03/27] MECONTRACT-242 - Fix typo in list of options. (#7) - list_of_options got truncated to ist_of_options - added back in the L --- k1many.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k1many.sh b/k1many.sh index ac9c0d77b7f..b5c3d17452f 100644 --- a/k1many.sh +++ b/k1many.sh @@ -66,7 +66,7 @@ if [ $# -lt 1 ] || [ $# -gt 4 ] ; then exit 1 fi -ist_of_options="--build --destroy --help --reboot --stop --start --restart" +list_of_options="--build --destroy --help --reboot --stop --start --restart" cwd=$( dirname "$PWD" ) count=0 for var in "$@" From 2acd9ba8263ac94137a10a5fa57fd9b5cbd31f37 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 12 Nov 2024 11:48:46 -0500 Subject: [PATCH 04/27] MECONTRACT-242 - Use the folder name as the project name so it is easier to recognize in the Docker UI. --- k1many.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/k1many.sh b/k1many.sh index b5c3d17452f..53e695ce9a8 100644 --- a/k1many.sh +++ b/k1many.sh @@ -139,11 +139,17 @@ do esac else + # Used to name the project according to the folder name + # which makes it easier to recognize who is who in Docker. + projectname="${var}" + + # Full path of the folder containing the Moodle files. folder="${cwd}/${var}" if [ ! -d "${folder}" ]; then echo "${folder} is not valid" exit 1 fi + # Start the site # Check the Moodle version. If its 4.5 then set php version to 8.3 export MOODLE_DOCKER_PHP_VERSION=8.1 @@ -155,21 +161,21 @@ do cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php case $count in "2") - export COMPOSE_PROJECT_NAME=site1 + export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=8000 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site1" --shortname="site1" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" echo "${folder} site started - port 8000" ;; "3") - export COMPOSE_PROJECT_NAME=site2 + export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=1234 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site2" --shortname="site1" --summary="Site 2" --adminpass="test" --adminemail="admin@example.com" echo "${folder} site started - port 1234" ;; "4") - export COMPOSE_PROJECT_NAME=site3 + export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=6789 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site3" --shortname="site3" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" From 170515753570fd46f1536d5c525b9497066dd026 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 12 Nov 2024 16:02:55 -0500 Subject: [PATCH 05/27] MECONTRACT-242 - Rename the Moodle instances according to folder's name. --- k1many.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/k1many.sh b/k1many.sh index 53e695ce9a8..28d62dc8bb0 100644 --- a/k1many.sh +++ b/k1many.sh @@ -83,7 +83,7 @@ do # Check for any swithes that don't need options. case $SWITCH in "--build") - if [ -n "$(docker ps -f "name=site1-webserver-1" -f "status=running" -q )" ]; then + if [ -n "$(docker ps -f "name=${var}-webserver-1" -f "status=running" -q )" ]; then echo "The first site is already running!. It cannot be re-initialized." exit 1 fi @@ -164,21 +164,21 @@ do export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=8000 start_server - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site1" --shortname="site1" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" echo "${folder} site started - port 8000" ;; "3") export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=1234 start_server - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site2" --shortname="site1" --summary="Site 2" --adminpass="test" --adminemail="admin@example.com" + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" echo "${folder} site started - port 1234" ;; "4") export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=6789 start_server - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="site3" --shortname="site3" --summary="Site 1" --adminpass="test" --adminemail="admin@example.com" + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" echo "${folder} site started - port 6789" ;; esac From b294bfba4726998665573fdac4a77387728e0de8 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 12 Nov 2024 16:08:37 -0500 Subject: [PATCH 06/27] MECONTRACT-242 - Added info_message() decorator. --- k1many.sh | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/k1many.sh b/k1many.sh index 28d62dc8bb0..2d121f74b24 100644 --- a/k1many.sh +++ b/k1many.sh @@ -24,6 +24,16 @@ help_messages () { " } +# Decorator to output information message to the user. +# Takes 1 param, then message to be displayed. +info_message() { + CYAN='\033[0;36m' + NC='\033[0m' # No Color + echo + echo "${CYAN}$1${NC}" + echo +} + start_server() { # Start the server bin/moodle-docker-compose up -d @@ -76,7 +86,7 @@ do SWITCH=${var} # Check to see if the list of arguments is valid. if exists_in_list "$list_of_options" " " $SWITCH; then - echo "Invalid option $SWITCH" + echo "Invalid option $SWITCH." help_messages exit 1 fi @@ -98,42 +108,42 @@ do ;; "--destroy") if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to shutdown" + info_message "No containers running. Nothing to shutdown." exit 1 fi docker stop $(docker ps -a -q) docker rm $(docker ps -a -q) - echo "All containers shut down and removed." + info_message "All containers shut down and removed." exit 1 ;; # Restart "--restart") if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to reboot" + info_message "No containers running. Nothing to reboot." exit 1 fi docker restart $(docker ps -q) - echo "All sites restarted" + info_message "All sites restarted." exit 1 ;; # Start "--start") if [ -n "$(docker ps -f "name=site1-webserver-1" -f "status=running" -q )" ]; then - echo "Sites are already running." + info_message "Sites are already running." exit 1 fi docker start $(docker ps -a -q -f status=exited) - echo "All sites started" + info_message "All sites started." exit 1 ;; # Stop "--stop") if ! docker ps | grep -q 'moodlehq'; then - echo "No containers running. Nothing to stop" + info_message "No containers running. Nothing to stop." exit 1 fi docker stop $(docker ps -q) - echo "All sites stopped" + info_message "All sites stopped." exit 1 ;; @@ -165,21 +175,21 @@ do export MOODLE_DOCKER_WEB_PORT=8000 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - echo "${folder} site started - port 8000" + info_message "${folder} site started - port 8000" ;; "3") export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=1234 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - echo "${folder} site started - port 1234" + info_message "${folder} site started - port 1234" ;; "4") export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=6789 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - echo "${folder} site started - port 6789" + info_message "${folder} site started - port 6789" ;; esac fi From c6a7b3454128a3308ca4d1e8a0ffee842d644ef1 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 12 Nov 2024 16:15:30 -0500 Subject: [PATCH 07/27] MECONTRACT-242 - Added error_message() decorator function. --- k1many.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/k1many.sh b/k1many.sh index 2d121f74b24..a4f04a93d10 100644 --- a/k1many.sh +++ b/k1many.sh @@ -34,6 +34,16 @@ info_message() { echo } +# Decorator to output error message to the user. +# Takes 1 param, then message to be displayed. +error_message() { + RED='\033[0;31m' + NC='\033[0m' # No Color + echo + echo "${RED}$1${NC}" + echo +} + start_server() { # Start the server bin/moodle-docker-compose up -d From c9594352dde6fdf1cd4e2f1daee54fd39f1d69cb Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 13 Nov 2024 15:51:32 -0500 Subject: [PATCH 08/27] MECONTRACT-242 - DRY COMPOSE_PROJECT_NAME. --- k1many.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/k1many.sh b/k1many.sh index a4f04a93d10..fa4c2c09741 100644 --- a/k1many.sh +++ b/k1many.sh @@ -178,28 +178,26 @@ do export MOODLE_DOCKER_PHP_VERSION=8.3 fi export MOODLE_DOCKER_WWWROOT=${folder} + export COMPOSE_PROJECT_NAME=${projectname} cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php case $count in "2") - export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=8000 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - info_message "${folder} site started - port 8000" + info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; "3") - export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=1234 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - info_message "${folder} site started - port 1234" + info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; "4") - export COMPOSE_PROJECT_NAME=${projectname} export MOODLE_DOCKER_WEB_PORT=6789 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - info_message "${folder} site started - port 6789" + info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; esac fi From b35379bbb409f6d3003826c010ce5f5d025a92c8 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 13 Nov 2024 15:54:15 -0500 Subject: [PATCH 09/27] MECONTRACT-242 - Set unique session cookie name to avoid login issue. --- k1many.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/k1many.sh b/k1many.sh index fa4c2c09741..030e404720c 100644 --- a/k1many.sh +++ b/k1many.sh @@ -183,20 +183,26 @@ do case $count in "2") export MOODLE_DOCKER_WEB_PORT=8000 + # Starts the container and wait for DB. start_server + # Install Moodle. bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" + # Set the session cookie to avoid login problem between instances. + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; "3") export MOODLE_DOCKER_WEB_PORT=1234 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; "4") export MOODLE_DOCKER_WEB_PORT=6789 start_server bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" ;; esac From fa315091b4a99317c69bb600c519f7e43b7b69c2 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Thu, 21 Nov 2024 11:45:43 -0500 Subject: [PATCH 10/27] MECONTRACT-242 - Use the error_message decorator to display error messages. --- k1many.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/k1many.sh b/k1many.sh index 030e404720c..f05f6dd479f 100644 --- a/k1many.sh +++ b/k1many.sh @@ -75,13 +75,13 @@ exists_in_list() { # COMPOSE_PROJECT_NAME - Docker project name - used to identify sites; if [ $# -eq 0 ]; then - echo "No arguments supplied" + error_message "No arguments supplied" help_messages exit 1 fi if [ $# -lt 1 ] || [ $# -gt 4 ] ; then - echo "Invalid number of arguments passed in. Must be between 1 and 4 arguments" + error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments" help_messages exit 1 fi @@ -96,7 +96,7 @@ do SWITCH=${var} # Check to see if the list of arguments is valid. if exists_in_list "$list_of_options" " " $SWITCH; then - echo "Invalid option $SWITCH." + error_message "Invalid option $SWITCH." help_messages exit 1 fi From acbaee65776f6b5056f71c999b1d282dd742f902 Mon Sep 17 00:00:00 2001 From: derek-henderson-K1 <140744865+derek-henderson-K1@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:18:02 -0500 Subject: [PATCH 11/27] MECONTRACT-246 - Update version of mariadb used. (#10) --- db.mariadb.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db.mariadb.yml b/db.mariadb.yml index b355dee9049..5fa75b18f99 100644 --- a/db.mariadb.yml +++ b/db.mariadb.yml @@ -4,7 +4,7 @@ services: MOODLE_DOCKER_DBTYPE: mariadb MOODLE_DOCKER_DBCOLLATION: utf8mb4_bin db: - image: mariadb:${MOODLE_DOCKER_DB_VERSION:-10.7} + image: mariadb:${MOODLE_DOCKER_DB_VERSION:-10.11.9} command: > --character-set-server=utf8mb4 --collation-server=utf8mb4_bin From f54951a9ea33b35194b42bb427265d5f0af8dd0f Mon Sep 17 00:00:00 2001 From: derek-henderson-K1 <140744865+derek-henderson-K1@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:43:47 -0500 Subject: [PATCH 12/27] MECONTRACK-250 - Remove deprecated version element from yml files. (#11) --- local.yml_many | 3 +-- local.yml_single | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/local.yml_many b/local.yml_many index 91187ff3fc0..2ed0a48abb6 100644 --- a/local.yml_many +++ b/local.yml_many @@ -1,4 +1,3 @@ -version: "2" services: webserver: extra_hosts: @@ -15,4 +14,4 @@ services: idekey=VSCODE discover_client_host=1 - \ No newline at end of file + diff --git a/local.yml_single b/local.yml_single index 8c1286fd046..4ef5deca548 100644 --- a/local.yml_single +++ b/local.yml_single @@ -1,4 +1,3 @@ -version: "2" services: webserver: extra_hosts: From 1b015665fe83444d59ab352f63295ee03e0532d9 Mon Sep 17 00:00:00 2001 From: Nicolas Dalpe <55551039+nicolas-dalpe@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:08:53 -0500 Subject: [PATCH 13/27] MECONTRACK-245 - Add xDebug to Docker on many instances (#17) * MECONTRACK-245 - Added xDebug config file in assets. * MECONTRACK-245 - Added k1many2.sh which introduces the build_instances function to add xDebug in the build process. * MECONTRACK-245 - Add a function to reset config files after sutting down or destroying containers. * MECONTRACK-245 - Created k1many3.sh to implement xdebug with --stop/--start. * MECONTRACK-245 - Modify xDebug log file path. * MECONTRACK-245 - Added k1many3.sh to add xDebug with --build and --start. * MECONTRACK-245 - On going task. Added xdebug to --start and --stop. * MECONTRACK-245 Update to xdebug on multiple sites. * MECONTRACK-245 - Support xDebug when --start & --stop. Add Excimer support. * MECONTRACK-245 - Rewrite the doc ( --help ). * MECONTRACK-245 - Removed K1many2.sh. * MECONTRACK-245 - Removed K1many.sh. * MECONTRACK-245 - Renamed k1many3.sh to k1many.sh. --- assets/php/docker-php-ext-xdebug.ini | 9 + k1many.sh | 413 ++++++++++++++++----------- local.yml | 15 +- local.yml_many | 5 +- 4 files changed, 266 insertions(+), 176 deletions(-) create mode 100644 assets/php/docker-php-ext-xdebug.ini mode change 100644 => 100755 k1many.sh diff --git a/assets/php/docker-php-ext-xdebug.ini b/assets/php/docker-php-ext-xdebug.ini new file mode 100644 index 00000000000..a6b650b024e --- /dev/null +++ b/assets/php/docker-php-ext-xdebug.ini @@ -0,0 +1,9 @@ +xdebug.mode = debug +xdebug.client_host = host.docker.internal +xdebug.idekey=VSCODE +xdebug.start_with_request=yes +xdebug.client_port=9003 +xdebug.log=/tmp/xdebug.log +xdebug.log_level=10 +xdebug.discover_client_host=1 +zend_extension=xdebug diff --git a/k1many.sh b/k1many.sh old mode 100644 new mode 100755 index f05f6dd479f..2d33cd71ec6 --- a/k1many.sh +++ b/k1many.sh @@ -1,57 +1,138 @@ -#!/bin/bash +#!/usr/bin/env bash + +# Define colors for various the output messages. +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color help_messages () { - echo "Usage: sh k1many.sh [option] [folder1] [folder2] [folder2]" - echo "Script that can start multiple sites." echo - echo "--build Start the site and initialize the sites." - echo "--destroy Stop the sites. Destroy all data" - echo "--help display this message" - echo "--restart Restart all running sites." - echo "--start Start all stopped sites." - echo "--stop Stop all running sites." - - echo "{folder1} -folder pointing to first Moodle site (Mandatory)" - echo "{folder2} -folder pointing to second Moodle site (optional)" - echo "{folder3} -folder pointing to third Moodle site (optional)" - echo " - Examples: - sh k1many.sh --build M405 # Start a site with the folder in docker/M405 folder - sh k1many.sh --build M405 M401 MT # Start three sites with based in docker/M405, docker/M401, docker/MT - sh k1many.sh --start # Start all stopped sites - sh k1many.sh --stop # Stop all stopped sites - sh k1many.sh --destroy # Stop and destroy sites - " + echo + echo -e "${GREEN}Usage:${NC}" + echo " Script that can start multiple Moodle instances." + echo " ./k1many.sh option folder1 [folder2] [folder3]" + echo + echo -e "${GREEN}Options:${NC}" + echo " --build Create and start the containers for the passed folders." + echo " --destroy Stop and remove all running containers. All data is lost." + echo " --help Display this message." + echo " --restart Restart all running containers." + echo " --start Start all stopped containers. Needs folder(s) path as well. See examples." + echo " --stop Stop all running containers." + echo + echo -e "${GREEN}Folders:${NC}" + echo " folder1 Folder pointing to first Moodle instance (Mandatory)." + echo " [folder2] Folder pointing to second Moodle instance (optional)." + echo " [folder3] Folder pointing to third Moodle instance (optional)." + echo + echo -e "${GREEN}Examples:${NC}" + echo " Start three Moodle instances. Path starts at /home/username/projects/[folder]." + echo " In this example, the fist Moodle instance will be in /home/username/projects/M405." + echo " ./k1many.sh --build M405 M401 MT" + echo + echo " Start all Moodle instances passed in script parameters. Same as --build." + echo " ./k1many.sh --start folder1 [folder2] [folder3]" + echo + echo " Stops all running containers." + echo " ./k1many.sh --stop" + echo + echo " Stops and removes all running containers. All data is lost." + echo " ./k1many.sh --destroy" + echo + echo } # Decorator to output information message to the user. # Takes 1 param, then message to be displayed. info_message() { - CYAN='\033[0;36m' - NC='\033[0m' # No Color echo - echo "${CYAN}$1${NC}" + echo -e "${CYAN}$1${NC}" echo } # Decorator to output error message to the user. # Takes 1 param, then message to be displayed. error_message() { - RED='\033[0;31m' - NC='\033[0m' # No Color echo - echo "${RED}$1${NC}" + echo -e "${RED}$1${NC}" echo } start_server() { - # Start the server - bin/moodle-docker-compose up -d - # Sleep for 6 seconds to allow database to come up - sleep 6 - # Just in case there is still some latency. - bin/moodle-docker-wait-for-db - return 0 + # Start the server + bin/moodle-docker-compose up -d + + # Sleep for 6 seconds to allow database to come up + # sleep 6 + + # Just in case there is still some latency. + bin/moodle-docker-wait-for-db +} + +start_instances() { + + # Project name. + projectname=$1 + + # Starts the container and wait for DB. + start_server + + info_message "${projectname} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" +} + +# Function to group the commands to build the each instances. +# The params are validated before this function is called. +build_instances() { + # Project name (folder that contains the Moodle files) + projectname=$1 + + # Full path of the Moodle folder. + folder=$2 + + # xDebug port. Must be different for each instances. + # xdebugport=$3 + + # Reset the xDebug config file from previous boot. + # We reset it to set the client port back 9003 to + # make sure the sed will find and replace it with + # the new client port. + # git checkout assets/php/docker-php-ext-xdebug.ini + + # Change xDebug port for this instance. + # sed -i -e 's/xdebug.client_port=9003/xdebug.client_port='"${xdebugport}"'/g' assets/php/docker-php-ext-xdebug.ini + + # Starts the container and wait for DB. + start_server + + # This is a Moodle admin plugin that provides developers with insights into + # not only what pages in your site are slow, but why. + # It uses the the Excimer sampling php profiler to so. + bin/moodle-docker-compose exec webserver pecl install excimer + bin/moodle-docker-compose exec webserver docker-php-ext-enable excimer + + # Install Moodle. + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" + + # Set the session cookie to avoid login problem between instances. + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" + + # Install xdebug extention in the new webserser. + # If already installed, the install will just fail. + bin/moodle-docker-compose exec webserver pecl install xdebug + + # Enable XDebug extension in Apache and restart the webserver container + bin/moodle-docker-compose exec webserver docker-php-ext-enable xdebug + bin/moodle-docker-compose restart webserver + + info_message "${folder} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" +} + +# This function resets all config files used during boot of project. +# Should be used when --destroy containers. +reset_config_files() { + rm local.yml + git checkout assets/php/docker-php-ext-xdebug.ini } exists_in_list() { @@ -67,146 +148,160 @@ exists_in_list() { return 0 } -# Variables -# MOODLE_DOCKER_DB - database used by Moodle - default maria db -# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located; -# MOODLE_DOCKER_PORT - port (default 8000); -# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1; -# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites; +validate_folder_path() { + if [ ! -d "${1}" ]; then + error_message "${1} is not a valid folder." + help_messages + exit 1 + fi +} + +################### +### Validations ### +if [ $# -eq 0 ]; then + error_message "No arguments supplied. See help message below." + help_messages + exit 1 +fi -if [ $# -eq 0 ]; then - error_message "No arguments supplied" +if [ $# -lt 1 ] || [ $# -gt 4 ]; then + error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments." help_messages exit 1 fi -if [ $# -lt 1 ] || [ $# -gt 4 ] ; then - error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments" +# Validate the switch passed to the script. +list_of_options="--build --destroy --help --reboot --stop --start --restart" +SWITCH=$1 +if exists_in_list "$list_of_options" " " $SWITCH; then + error_message "Invalid option $SWITCH." help_messages exit 1 fi -list_of_options="--build --destroy --help --reboot --stop --start --restart" +# Display help message if the --help switch is present. +if [ "$SWITCH" = "--help" ]; then + help_messages + exit 0 +fi + +######################## +### Global variables ### +# MOODLE_DOCKER_DB - database used by Moodle - default maria db +# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located; +# MOODLE_DOCKER_PORT - port (default 8000); +# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1; +# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites; + +# We always use Maria DB for all our Moodle. +export MOODLE_DOCKER_DB=mariadb + +# Current working dir. +# Typically gives /home/username/projects. cwd=$( dirname "$PWD" ) -count=0 -for var in "$@" -do - count=$((count+1)) - if [ "$count" -eq 1 ]; then - SWITCH=${var} - # Check to see if the list of arguments is valid. - if exists_in_list "$list_of_options" " " $SWITCH; then - error_message "Invalid option $SWITCH." - help_messages + +# Moodle Docker Port. +# AKA which port the webserver container will listen to. +moodleDockerPort=(8000 1234 5678) + +# xDebug ports +# Each containers must have a their own port. +xdebugPort=(9003 9004 9005) + +# Use the multiple instances local.yml file. +cp local.yml_many local.yml + +################################################ +### Process swithes that don't need options. ### +case $SWITCH in + "--destroy") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to shutdown." exit 1 fi - # Check for any swithes that don't need options. - case $SWITCH in - "--build") - if [ -n "$(docker ps -f "name=${var}-webserver-1" -f "status=running" -q )" ]; then - echo "The first site is already running!. It cannot be re-initialized." - exit 1 - fi - # Do the basics to start the site. - export MOODLE_DOCKER_DB=mariadb - export COMPOSE_PROJECT_NAME=site1 - cp local.yml_many local.yml - ;; - "--help") - help_messages - exit 1 - ;; - "--destroy") - if ! docker ps | grep -q 'moodlehq'; then - info_message "No containers running. Nothing to shutdown." - exit 1 - fi - docker stop $(docker ps -a -q) - docker rm $(docker ps -a -q) - info_message "All containers shut down and removed." - exit 1 - ;; - # Restart - "--restart") - if ! docker ps | grep -q 'moodlehq'; then - info_message "No containers running. Nothing to reboot." - exit 1 - fi - docker restart $(docker ps -q) - info_message "All sites restarted." - exit 1 - ;; - # Start - "--start") - if [ -n "$(docker ps -f "name=site1-webserver-1" -f "status=running" -q )" ]; then - info_message "Sites are already running." - exit 1 - fi - docker start $(docker ps -a -q -f status=exited) - info_message "All sites started." - exit 1 - ;; - # Stop - "--stop") - if ! docker ps | grep -q 'moodlehq'; then - info_message "No containers running. Nothing to stop." - exit 1 - fi - docker stop $(docker ps -q) - info_message "All sites stopped." - exit 1 - ;; - - esac - else - # Used to name the project according to the folder name - # which makes it easier to recognize who is who in Docker. - projectname="${var}" - - # Full path of the folder containing the Moodle files. - folder="${cwd}/${var}" - if [ ! -d "${folder}" ]; then - echo "${folder} is not valid" + docker stop $(docker ps -a -q) + docker rm $(docker ps -a -q) + reset_config_files + info_message "All containers shut down and removed." + exit 1 + ;; + "--restart") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to reboot." exit 1 fi - - # Start the site - # Check the Moodle version. If its 4.5 then set php version to 8.3 - export MOODLE_DOCKER_PHP_VERSION=8.1 - moodlever=$(grep "$branch = '405';" $folder/version.php) - if [ "$moodlever" ]; then - export MOODLE_DOCKER_PHP_VERSION=8.3 + docker restart $(docker ps -q) + info_message "All sites restarted." + exit 1 + ;; + "--stop") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to stop." + exit 1 fi - export MOODLE_DOCKER_WWWROOT=${folder} - export COMPOSE_PROJECT_NAME=${projectname} - cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php - case $count in - "2") - export MOODLE_DOCKER_WEB_PORT=8000 - # Starts the container and wait for DB. - start_server - # Install Moodle. - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - # Set the session cookie to avoid login problem between instances. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" - info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" - ;; - "3") - export MOODLE_DOCKER_WEB_PORT=1234 - start_server - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" - info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" + docker stop $(docker ps -q) + # reset_config_files + info_message "All sites stopped." + exit 1 + ;; +esac + +############################################# +### Process swithes that require options. ### + +# Ignore first parm passed to the script. +# Skip the --switch to cycle the folders in argument. +shift + +iteratior=0 + +# Iterate the passed folders. +for i in "$@" +do + # Folder passed in args to the script. + argfolder="$i" + + # Full system path of the Moodle instance. + validate_folder_path "${cwd}/${argfolder}" + fullfolderpath="${cwd}/${argfolder}" + export MOODLE_DOCKER_WWWROOT=${fullfolderpath} + + # Check the Moodle version. If its 4.5 then set php version to 8.3. + export MOODLE_DOCKER_PHP_VERSION=8.1 + moodlever=$(grep "$branch = '405';" $fullfolderpath/version.php) + if [ "$moodlever" ]; then + export MOODLE_DOCKER_PHP_VERSION=8.3 + fi + + # Used to name the project according to the folder name + # which makes it easier to recognize who is who in Docker. + projectname="${argfolder}" + export COMPOSE_PROJECT_NAME=${projectname} + + # Set the port for the webserver. + export MOODLE_DOCKER_WEB_PORT="${moodleDockerPort[$iteratior]}" + + # Copy the config.php file to the Moodle folder. + cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php + + case $SWITCH in + "--build") + if [ -n "$(docker ps -f "name=${projectname}-webserver-1" -f "status=running" -q )" ]; then + error_message "The first site is already running! It cannot be re-initialized." + exit 1 + fi + + # Build containers and install Moodle. + build_instances ${projectname} ${fullfolderpath} "${xdebugPort[$iteratior]}" ;; - "4") - export MOODLE_DOCKER_WEB_PORT=6789 - start_server - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" - info_message "${folder} site started - http://localhost:${MOODLE_DOCKER_WEB_PORT}" + "--start") + + # Start all Moodle instances. + start_instances ${projectname} "${xdebugPort[$iteratior]}" ;; - esac - fi -done + esac -return + # Increment loop counter. + iteratior=$((iteratior+1)) +done +exit 0 diff --git a/local.yml b/local.yml index 8c1286fd046..77f724c604f 100644 --- a/local.yml +++ b/local.yml @@ -5,6 +5,7 @@ services: - "host.docker.internal:host-gateway" volumes: - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" environment: XDEBUG_MODE: debug,develop XDEBUG_CONFIG: @@ -14,18 +15,4 @@ services: log_level=10 idekey=VSCODE discover_client_host=1 - - adminer: - image: adminer:latest - container_name: "${COMPOSE_PROJECT_NAME}-Adminer" - environment: - ADMINER_DEFAULT_SERVER: db - ADMINER_PLUGINS: tables-filter - MYSQL_DATABASE: moodle - MYSQL_USER: moodle - MYSQL_PASSWORD: m@0dl3ing - build: - context: "./bin/Adminer/" - ports: - - 8089:8080 diff --git a/local.yml_many b/local.yml_many index 2ed0a48abb6..e5e7870e218 100644 --- a/local.yml_many +++ b/local.yml_many @@ -3,7 +3,8 @@ services: extra_hosts: - "host.docker.internal:host-gateway" volumes: - - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" environment: XDEBUG_MODE: debug,develop XDEBUG_CONFIG: @@ -13,5 +14,3 @@ services: log_level=10 idekey=VSCODE discover_client_host=1 - - From 76c9c161119874178b55ff1912dc581ccb893e1c Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:23:02 -0400 Subject: [PATCH 14/27] MECONTRACK-216 - Disable course recycle bin. --- k1many.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/k1many.sh b/k1many.sh index 2d33cd71ec6..5647d54c545 100755 --- a/k1many.sh +++ b/k1many.sh @@ -117,6 +117,9 @@ build_instances() { # Set the session cookie to avoid login problem between instances. bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" + # Enable course recycle bin + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 689511601a812df11332901fbd21da55b9a15b67 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:25:49 -0400 Subject: [PATCH 15/27] MECONTRACK-216 - Do not include users in course backup. --- k1many.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/k1many.sh b/k1many.sh index 5647d54c545..8176fd61272 100755 --- a/k1many.sh +++ b/k1many.sh @@ -120,6 +120,11 @@ build_instances() { # Enable course recycle bin bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 + # Include users in course backup + # Sets the default for whether to include users in backups. + php admin/cli/cfg.php --component=backup --name=backup_general_users --set=0 + + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From e7fe895e027902539617bb12f547f5bda8794d5b Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:31:01 -0400 Subject: [PATCH 16/27] MECONTRACK-216 - Disable automatically check for available updates. --- k1many.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/k1many.sh b/k1many.sh index 8176fd61272..cc78f13eef1 100755 --- a/k1many.sh +++ b/k1many.sh @@ -124,6 +124,11 @@ build_instances() { # Sets the default for whether to include users in backups. php admin/cli/cfg.php --component=backup --name=backup_general_users --set=0 + # Automatically check for available updates + # If enabled, your site will automatically check for available updates + # for both Moodle code and all additional plugins. If there is a new update + # available, a notification will be sent to site admins. + php admin/cli/cfg.php --component=backup --name=updateautocheck --set=0 # Install xdebug extention in the new webserser. # If already installed, the install will just fail. From bc2e74d0e7fa5bd8e26dce3f871059d5f3ad0a70 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:35:25 -0400 Subject: [PATCH 17/27] MECONTRACK-216 - Force user to login and disable dashboard for guest. --- k1many.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/k1many.sh b/k1many.sh index cc78f13eef1..5db7a472e18 100755 --- a/k1many.sh +++ b/k1many.sh @@ -128,7 +128,19 @@ build_instances() { # If enabled, your site will automatically check for available updates # for both Moodle code and all additional plugins. If there is a new update # available, a notification will be sent to site admins. - php admin/cli/cfg.php --component=backup --name=updateautocheck --set=0 + php admin/cli/cfg.php --name=updateautocheck --set=0 + + # Allow guest access to Dashboard + # If enabled guests can access Dashboard, otherwise guests are + # redirected to the site front page. + php admin/cli/cfg.php --name=allowguestmymoodle --set=0 + + # Force users to log in + # Normally, the front page of the site and the course listings (but not courses) + # can be read by people without logging in to the site. If you want to force + # people to log in before they do ANYTHING on the site, + # then you should enable this setting. + php admin/cli/cfg.php --name=forcelogin --set=1 # Install xdebug extention in the new webserser. # If already installed, the install will just fail. From aa2d62eff43d4511057c0b529d5eb402aea8c9a7 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:39:11 -0400 Subject: [PATCH 18/27] MECONTRACK-216 - Set default country, city and timezone. --- k1many.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/k1many.sh b/k1many.sh index 5db7a472e18..dd4780e8e6c 100755 --- a/k1many.sh +++ b/k1many.sh @@ -142,6 +142,22 @@ build_instances() { # then you should enable this setting. php admin/cli/cfg.php --name=forcelogin --set=1 + # Default country + # If you set a country here, then this country will be selected by default + # on new user accounts. To force users to choose a country, just leave this unset. + php admin/cli/cfg.php --name=country --set=CA + + # Default city + # A city entered here will be the default city when creating new user accounts. + php admin/cli/cfg.php --name=defaultcity --set=Montreal + + # Default timezone + # This is the default timezone for displaying dates - each user can override + # this setting in their profile. Cron tasks and other server settings are + # specified in this timezone. You should change the setting if it shows + # as "Invalid timezone" + php admin/cli/cfg.php --name=timezone --set=America/Toronto + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 110aebd442160f045c78d8b45d30b8f0e6d0ea07 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:41:03 -0400 Subject: [PATCH 19/27] MECONTRACK-216 - Hide guest login button on login page. --- k1many.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/k1many.sh b/k1many.sh index dd4780e8e6c..498a74dab2b 100755 --- a/k1many.sh +++ b/k1many.sh @@ -158,6 +158,10 @@ build_instances() { # as "Invalid timezone" php admin/cli/cfg.php --name=timezone --set=America/Toronto + # Guest login button + # You can hide or show the guest login button on the login page. + php admin/cli/cfg.php --name=guestloginbutton --set=0 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 833ef77f181b7cd7156b08d61136d7db1e01c397 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:45:24 -0400 Subject: [PATCH 20/27] MECONTRACK-216 - Do not notify about new builds. --- k1many.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/k1many.sh b/k1many.sh index 498a74dab2b..ef6a394878f 100755 --- a/k1many.sh +++ b/k1many.sh @@ -130,6 +130,14 @@ build_instances() { # available, a notification will be sent to site admins. php admin/cli/cfg.php --name=updateautocheck --set=0 + # Notify about new builds + # If enabled, the available update for Moodle code is also reported when a + # new build for the current version is available. Builds are continuous + # improvements of a given Moodle version. They are generally released every week. + # If disabled, the available update will be reported only when there is a + # higher version of Moodle released. Checks for plugins are not affected by this setting. + php admin/cli/cfg.php --name=updatenotifybuilds --set=0 + # Allow guest access to Dashboard # If enabled guests can access Dashboard, otherwise guests are # redirected to the site front page. From 25bc5d2900a2c20a0570c437b7baeb617b231984 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 23 Apr 2025 11:48:10 -0400 Subject: [PATCH 21/27] MECONTRACK-216 - Disable analytics and statistics. --- k1many.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/k1many.sh b/k1many.sh index ef6a394878f..7bd1cebe20f 100755 --- a/k1many.sh +++ b/k1many.sh @@ -170,6 +170,19 @@ build_instances() { # You can hide or show the guest login button on the login page. php admin/cli/cfg.php --name=guestloginbutton --set=0 + # Analytics + # Analytics models, such as 'Students at risk of dropping out' or 'Upcoming activities due', + # can generate predictions, send insight notifications and offer further actions + # such as messaging users. + php admin/cli/cfg.php --name=enableanalytics --set=0 + + # Enable statistics + # If you choose 'yes' here, Moodle's cronjob will process the logs and gather some statistics. + # Depending on the amount of traffic on your site, this can take awhile. If you enable this, + # you will be able to see some interesting graphs and statistics about each of your courses, + # or on a sitewide basis. + php admin/cli/cfg.php --name=enablestats --set=0 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 2c541e2e79ce848a71fe3453884da233bf7e3e4a Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Thu, 8 May 2025 15:47:51 -0400 Subject: [PATCH 22/27] MECONTRACK-216 - Set default Moodle settings during --build process. --- k1many.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/k1many.sh b/k1many.sh index 7bd1cebe20f..f7e1f898141 100755 --- a/k1many.sh +++ b/k1many.sh @@ -122,13 +122,13 @@ build_instances() { # Include users in course backup # Sets the default for whether to include users in backups. - php admin/cli/cfg.php --component=backup --name=backup_general_users --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --component=backup --name=backup_general_users --set=0 # Automatically check for available updates # If enabled, your site will automatically check for available updates # for both Moodle code and all additional plugins. If there is a new update # available, a notification will be sent to site admins. - php admin/cli/cfg.php --name=updateautocheck --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=updateautocheck --set=0 # Notify about new builds # If enabled, the available update for Moodle code is also reported when a @@ -136,52 +136,52 @@ build_instances() { # improvements of a given Moodle version. They are generally released every week. # If disabled, the available update will be reported only when there is a # higher version of Moodle released. Checks for plugins are not affected by this setting. - php admin/cli/cfg.php --name=updatenotifybuilds --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=updatenotifybuilds --set=0 # Allow guest access to Dashboard # If enabled guests can access Dashboard, otherwise guests are # redirected to the site front page. - php admin/cli/cfg.php --name=allowguestmymoodle --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=allowguestmymoodle --set=0 # Force users to log in # Normally, the front page of the site and the course listings (but not courses) # can be read by people without logging in to the site. If you want to force # people to log in before they do ANYTHING on the site, # then you should enable this setting. - php admin/cli/cfg.php --name=forcelogin --set=1 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=forcelogin --set=1 # Default country # If you set a country here, then this country will be selected by default # on new user accounts. To force users to choose a country, just leave this unset. - php admin/cli/cfg.php --name=country --set=CA + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=country --set=CA # Default city # A city entered here will be the default city when creating new user accounts. - php admin/cli/cfg.php --name=defaultcity --set=Montreal + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=defaultcity --set=Montreal # Default timezone # This is the default timezone for displaying dates - each user can override # this setting in their profile. Cron tasks and other server settings are # specified in this timezone. You should change the setting if it shows # as "Invalid timezone" - php admin/cli/cfg.php --name=timezone --set=America/Toronto + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=timezone --set=America/Toronto # Guest login button # You can hide or show the guest login button on the login page. - php admin/cli/cfg.php --name=guestloginbutton --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=guestloginbutton --set=0 # Analytics # Analytics models, such as 'Students at risk of dropping out' or 'Upcoming activities due', # can generate predictions, send insight notifications and offer further actions # such as messaging users. - php admin/cli/cfg.php --name=enableanalytics --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=enableanalytics --set=0 # Enable statistics # If you choose 'yes' here, Moodle's cronjob will process the logs and gather some statistics. # Depending on the amount of traffic on your site, this can take awhile. If you enable this, # you will be able to see some interesting graphs and statistics about each of your courses, # or on a sitewide basis. - php admin/cli/cfg.php --name=enablestats --set=0 + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=enablestats --set=0 # Install xdebug extention in the new webserser. # If already installed, the install will just fail. From f7cb7cd545ff8aefe32c09f94594ba74204ccd4e Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 27 May 2025 11:16:25 -0400 Subject: [PATCH 23/27] MECONTRACK-216 - Disable course recycle bin during --build process. --- k1many.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/k1many.sh b/k1many.sh index f7e1f898141..e1dbf8c1d2d 100755 --- a/k1many.sh +++ b/k1many.sh @@ -183,6 +183,9 @@ build_instances() { # or on a sitewide basis. bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=enablestats --set=0 + # Enable course recycle bin + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 0969970c4d4465a3a9e60137a3d6ad5fb7a8fad9 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Tue, 27 May 2025 11:17:25 -0400 Subject: [PATCH 24/27] MECONTRACK-216 - Disable category recycle bin during --build process. --- k1many.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/k1many.sh b/k1many.sh index e1dbf8c1d2d..1a943194441 100755 --- a/k1many.sh +++ b/k1many.sh @@ -186,6 +186,9 @@ build_instances() { # Enable course recycle bin bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 + # Enable category recycle bin + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=categorybinenable --set=0 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From 76926c0d36ab4cf80b45c59cbb94b8d6d5372c90 Mon Sep 17 00:00:00 2001 From: nicolas-dalpe Date: Wed, 6 Aug 2025 09:50:08 -0400 Subject: [PATCH 25/27] MECONTRACK-216 - Disable indexing by search engines during --build process. --- k1many.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/k1many.sh b/k1many.sh index 1a943194441..e460b0aa3c1 100755 --- a/k1many.sh +++ b/k1many.sh @@ -150,6 +150,13 @@ build_instances() { # then you should enable this setting. bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=forcelogin --set=1 + # Force users to log in for profiles + # This setting forces people to log in as a real (non-guest) account before viewing any + # user's profile. If you disabled this setting, you may find that some users post + # advertising (spam) or other inappropriate content in their profiles, which is + # then visible to the whole world. + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=forceloginforprofiles --set=1 + # Default country # If you set a country here, then this country will be selected by default # on new user accounts. To force users to choose a country, just leave this unset. @@ -189,6 +196,18 @@ build_instances() { # Enable category recycle bin bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=categorybinenable --set=0 + # Allow indexing by search engines + # This determines whether to allow search engines to index your site. "Everywhere" will allow + # the search engines to search everywhere including login and signup pages, which means sites + # with Force Login turned on are still indexed. To avoid the risk of spam involved with the + # signup page being searchable, use "Everywhere except login and signup pages". + # "Nowhere" will tell search engines not to index any page. Note this is only a tag in the + # header of the site. It is up to the search engine to respect the tag. + # 0 = Everywhere except login and signup pages + # 1 = Everywhere + # 2 = Nowhere + bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=allowsearchengines --set=2 + # Install xdebug extention in the new webserser. # If already installed, the install will just fail. bin/moodle-docker-compose exec webserver pecl install xdebug From a27186e9b7f581200d66b03a460d49d50f3d58a1 Mon Sep 17 00:00:00 2001 From: hafid-feghouli-k1 Date: Tue, 7 Oct 2025 16:11:57 -0400 Subject: [PATCH 26/27] Removed environment parameters to centralize configuration in k1many.sh. --- local.yml_many | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/local.yml_many b/local.yml_many index e5e7870e218..6be642b6788 100644 --- a/local.yml_many +++ b/local.yml_many @@ -3,14 +3,5 @@ services: extra_hosts: - "host.docker.internal:host-gateway" volumes: - - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" - - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" - environment: - XDEBUG_MODE: debug,develop - XDEBUG_CONFIG: - client_host=host.docker.internal - start_with_request=yes - log=./tmp/xdebug.log - log_level=10 - idekey=VSCODE - discover_client_host=1 + - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" From 758068f68ab6bb84b1a36aa3d3be8796a7166686 Mon Sep 17 00:00:00 2001 From: hafid-feghouli-k1 Date: Tue, 7 Oct 2025 16:14:09 -0400 Subject: [PATCH 27/27] Refactored script to support new Moodle folder architecture and Moodle requirements depending on versions. --- k1many.sh | 571 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 346 insertions(+), 225 deletions(-) diff --git a/k1many.sh b/k1many.sh index e460b0aa3c1..1ff1a909672 100755 --- a/k1many.sh +++ b/k1many.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Define colors for various the output messages. +# Define colors for various output messages. RED='\033[0;31m' GREEN='\033[0;32m' CYAN='\033[0;36m' @@ -11,15 +11,16 @@ help_messages () { echo echo -e "${GREEN}Usage:${NC}" echo " Script that can start multiple Moodle instances." - echo " ./k1many.sh option folder1 [folder2] [folder3]" + echo " ./k1many.sh option folder1 [folder2] [folder3] [--debug]" echo echo -e "${GREEN}Options:${NC}" echo " --build Create and start the containers for the passed folders." echo " --destroy Stop and remove all running containers. All data is lost." echo " --help Display this message." echo " --restart Restart all running containers." - echo " --start Start all stopped containers. Needs folder(s) path as well. See examples." + echo " --start Start all stopped containers. Needs folder(s) path as well." echo " --stop Stop all running containers." + echo " --debug Enable verbose debug output for troubleshooting." echo echo -e "${GREEN}Folders:${NC}" echo " folder1 Folder pointing to first Moodle instance (Mandatory)." @@ -27,24 +28,21 @@ help_messages () { echo " [folder3] Folder pointing to third Moodle instance (optional)." echo echo -e "${GREEN}Examples:${NC}" - echo " Start three Moodle instances. Path starts at /home/username/projects/[folder]." - echo " In this example, the fist Moodle instance will be in /home/username/projects/M405." - echo " ./k1many.sh --build M405 M401 MT" - echo - echo " Start all Moodle instances passed in script parameters. Same as --build." - echo " ./k1many.sh --start folder1 [folder2] [folder3]" - echo - echo " Stops all running containers." + echo " Start three Moodle instances in /home/username/projects/[folder]." + echo " In this example, the first Moodle instance will be in /home/username/projects/M405:" + echo " ./k1many.sh --build M405 M401 M501 --debug" + echo " Start all Moodle instances passed in parameters:" + echo " ./k1many.sh --start M405 M401 M501" + echo " Stop all running containers:" echo " ./k1many.sh --stop" - echo - echo " Stops and removes all running containers. All data is lost." + echo " Stop and destroy all containers and data:" echo " ./k1many.sh --destroy" echo echo } # Decorator to output information message to the user. -# Takes 1 param, then message to be displayed. +# Takes 1 param, the message to be displayed. info_message() { echo echo -e "${CYAN}$1${NC}" @@ -52,185 +50,310 @@ info_message() { } # Decorator to output error message to the user. -# Takes 1 param, then message to be displayed. +# Takes 1 param, the message to be displayed. error_message() { echo echo -e "${RED}$1${NC}" echo } +# Debug message, only output if DEBUG is true. +# Takes 1 param, the message to be displayed. +debug_message() { + if [ "$DEBUG" = true ]; then + echo -e "${CYAN}[DEBUG] $1${NC}" + fi +} + +# Determines Moodle version-specific settings (PHP version, document root, CLI path, DB version). +# Args: +# $1: Full path to the Moodle folder. +# Sets global variables: +# MOODLE_DOCKER_PHP_VERSION: PHP version for the Docker image (e.g., 8.3). +# MOODLE_DOCKER_DB_VERSION: MariaDB version (e.g., 10.6). +# DOCUMENT_ROOT: Apache DocumentRoot (e.g., /var/www/html/public for Moodle 5.1). +# CLI_PATH: Path to CLI scripts (e.g., admin/cli/). +# PLUGIN_PREFIX: Prefix for plugin paths (e.g., /public for Moodle 5.1). +configure_moodle_version() { + local folder=$1 + local version_file + local branch + local grep_output + # Check for version.php in root or public folder + if [ -f "${folder}/version.php" ]; then + version_file="${folder}/version.php" + elif [ -f "${folder}/public/version.php" ]; then + version_file="${folder}/public/version.php" + else + error_message "version.php not found in ${folder} or ${folder}/public" + exit 1 + fi + debug_message "Checking version.php at ${version_file}" + # Extract $branch from version.php (matches $branch = '[number]';) + grep_output=$(grep "\$branch\s*=\s*['\"][0-9]\+['\"];" "${version_file}" || true) + debug_message "grep output: '${grep_output}'" + branch=$(echo "${grep_output}" | sed -E "s/.*['\"]([0-9]+)['\"];.*/\1/" || true) + debug_message "Extracted branch: '${branch}'" + if [ -z "$branch" ]; then + error_message "Failed to extract branch from ${version_file}" + exit 1 + fi + # Default settings (for older Moodle versions). + MOODLE_DOCKER_PHP_VERSION=8.1 + MOODLE_DOCKER_DB_VERSION=10.2 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + # Version-specific settings. + case "$branch" in + "501") + # Moodle 5.1: Requires PHP 8.3, MariaDB 10.11+, DocumentRoot /var/www/html/public. + MOODLE_DOCKER_PHP_VERSION=8.3 + MOODLE_DOCKER_DB_VERSION=10.11 + DOCUMENT_ROOT="/var/www/html/public" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="/public" + info_message "Detected Moodle 5.1 (branch ${branch}): Using PHP 8.3, MariaDB 10.11, DocumentRoot ${DOCUMENT_ROOT}." + ;; + "405") + # Moodle 4.5: Requires PHP 8.3, MariaDB 10.6+, traditional structure. + MOODLE_DOCKER_PHP_VERSION=8.3 + MOODLE_DOCKER_DB_VERSION=10.6 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + info_message "Detected Moodle 4.5 (branch ${branch}): Using PHP 8.3, MariaDB 10.6." + ;; + "401") + # Moodle 4.1: Requires PHP 8.1, MariaDB 10.4+, traditional structure. + MOODLE_DOCKER_PHP_VERSION=8.1 + MOODLE_DOCKER_DB_VERSION=10.4 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + info_message "Detected Moodle 4.1 (branch ${branch}): Using PHP 8.1, MariaDB 10.4." + ;; + *) + # Default to PHP 8.1 and MariaDB 10.2 for unrecognized or older branches + info_message "Unrecognized Moodle branch '${branch}' in ${version_file}. Using default PHP 8.1, MariaDB 10.2." + ;; + esac + # Export variables for use in the script. + export MOODLE_DOCKER_PHP_VERSION + export MOODLE_DOCKER_DB_VERSION + export DOCUMENT_ROOT + export CLI_PATH + export PLUGIN_PREFIX +} + start_server() { - # Start the server - bin/moodle-docker-compose up -d - # Sleep for 6 seconds to allow database to come up + # Start the server. + bin/moodle-docker-compose up -d + info_message "Started Docker containers for ${COMPOSE_PROJECT_NAME}" + + # Sleep for 6 seconds to allow database to come up. # sleep 6 # Just in case there is still some latency. bin/moodle-docker-wait-for-db + info_message "Database is ready for ${COMPOSE_PROJECT_NAME}" } start_instances() { - # Project name. - projectname=$1 + local projectname=$1 - # Starts the container and wait for DB. - start_server + # Configure Moodle version-specific settings. + configure_moodle_version "${fullfolderpath}" + # Start the container and wait for DB. + start_server info_message "${projectname} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" } -# Function to group the commands to build the each instances. -# The params are validated before this function is called. build_instances() { - # Project name (folder that contains the Moodle files) - projectname=$1 - - # Full path of the Moodle folder. - folder=$2 - - # xDebug port. Must be different for each instances. - # xdebugport=$3 - - # Reset the xDebug config file from previous boot. - # We reset it to set the client port back 9003 to - # make sure the sed will find and replace it with - # the new client port. - # git checkout assets/php/docker-php-ext-xdebug.ini - # Change xDebug port for this instance. - # sed -i -e 's/xdebug.client_port=9003/xdebug.client_port='"${xdebugport}"'/g' assets/php/docker-php-ext-xdebug.ini - - # Starts the container and wait for DB. + local projectname=$1 + local folder=$2 + local xdebug_port=${xDebugPort[$iterator]} + + # Configure Moodle version-specific settings. + configure_moodle_version "${folder}" + + # Install tool_excimer plugin on host. + local plugin_dir="${folder}${PLUGIN_PREFIX}/admin/tool" + mkdir -p "${plugin_dir}" + + # Only clone if the directory doesn't exist. + if [ ! -d "${plugin_dir}/excimer" ]; then + git clone https://github.com/catalyst/moodle-tool_excimer.git "${plugin_dir}/excimer" || { + info_message "Warning: Failed to clone tool_excimer plugin for ${projectname} (directory may already exist)" + } + else + info_message "tool_excimer plugin already exists at ${plugin_dir}/excimer for ${projectname}, skipping clone" + fi + info_message "Ensured tool_excimer plugin for ${projectname} at ${plugin_dir}/excimer" + debug_message "Using port ${MOODLE_DOCKER_WEB_PORT} for ${projectname}" + + # Copy the config.php file to the Moodle folder. + cp config.docker-template.php "${folder}/config.php" + debug_message "config.php will dynamically set wwwroot to http://localhost:${MOODLE_DOCKER_WEB_PORT} at runtime via env vars" + + # Add wwwrootcheck = false to prevent redirect loops. + echo "\$CFG->wwwrootcheck = false;" >> "${folder}/config.php" + info_message "Added \$CFG->wwwrootcheck = false to ${folder}/config.php to prevent redirect loops" + + # Update XDebug configuration. + local xdebug_config_file="assets/php/docker-php-ext-xdebug.ini" + cp "${xdebug_config_file}" "${xdebug_config_file}.bak" || { + error_message "Failed to backup ${xdebug_config_file}" + exit 1 + } + cat > "${xdebug_config_file}" <' >> /etc/apache2/sites-available/000-default.conf && + echo ' Options Indexes FollowSymLinks' >> /etc/apache2/sites-available/000-default.conf && + echo ' AllowOverride All' >> /etc/apache2/sites-available/000-default.conf && + echo ' Require all granted' >> /etc/apache2/sites-available/000-default.conf && + echo '' >> /etc/apache2/sites-available/000-default.conf && + a2enmod rewrite && + apache2ctl configtest + " || { + error_message "Apache config test failed for ${projectname}" + exit 1 + } + bin/moodle-docker-compose restart webserver + info_message "Restarted webserver after updating DocumentRoot to ${DOCUMENT_ROOT} for ${projectname} and enabled mod_rewrite" + fi + + # Debug checks (optional). + if [ "$DEBUG" = true ]; then + debug_message "Verifying Apache DocumentRoot for ${projectname}:" + bin/moodle-docker-compose exec webserver grep "DocumentRoot" /etc/apache2/sites-available/000-default.conf || echo "DocumentRoot not found" + debug_message "Verifying PHP version for ${projectname}:" + bin/moodle-docker-compose exec webserver php -v | grep "PHP ${MOODLE_DOCKER_PHP_VERSION}" || echo "PHP version check failed" + debug_message "Verifying Apache modules for ${projectname}:" + bin/moodle-docker-compose exec webserver apache2ctl -M | grep php || echo "PHP module not found" + debug_message "Verifying key files for ${projectname} in container:" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/index.php || echo "Root index.php not found" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/public/index.php || echo "Public index.php not found" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/public/login/index.php || echo "Public login/index.php not found" + fi + + # Install Excimer PHP extension. + bin/moodle-docker-compose exec webserver bash -c "pecl channel-update pecl.php.net && pecl install excimer && docker-php-ext-enable excimer" || { + error_message "Failed to install Excimer for ${projectname}" + exit 1 + } + info_message "Installed and enabled Excimer PHP extension for ${projectname}" + # Install Moodle. - bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" - - # Set the session cookie to avoid login problem between instances. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=sessioncookie --set="${projectname}" - - # Enable course recycle bin - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 - - # Include users in course backup - # Sets the default for whether to include users in backups. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --component=backup --name=backup_general_users --set=0 - - # Automatically check for available updates - # If enabled, your site will automatically check for available updates - # for both Moodle code and all additional plugins. If there is a new update - # available, a notification will be sent to site admins. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=updateautocheck --set=0 - - # Notify about new builds - # If enabled, the available update for Moodle code is also reported when a - # new build for the current version is available. Builds are continuous - # improvements of a given Moodle version. They are generally released every week. - # If disabled, the available update will be reported only when there is a - # higher version of Moodle released. Checks for plugins are not affected by this setting. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=updatenotifybuilds --set=0 - - # Allow guest access to Dashboard - # If enabled guests can access Dashboard, otherwise guests are - # redirected to the site front page. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=allowguestmymoodle --set=0 - - # Force users to log in - # Normally, the front page of the site and the course listings (but not courses) - # can be read by people without logging in to the site. If you want to force - # people to log in before they do ANYTHING on the site, - # then you should enable this setting. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=forcelogin --set=1 - - # Force users to log in for profiles - # This setting forces people to log in as a real (non-guest) account before viewing any - # user's profile. If you disabled this setting, you may find that some users post - # advertising (spam) or other inappropriate content in their profiles, which is - # then visible to the whole world. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=forceloginforprofiles --set=1 - - # Default country - # If you set a country here, then this country will be selected by default - # on new user accounts. To force users to choose a country, just leave this unset. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=country --set=CA - - # Default city - # A city entered here will be the default city when creating new user accounts. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=defaultcity --set=Montreal - - # Default timezone - # This is the default timezone for displaying dates - each user can override - # this setting in their profile. Cron tasks and other server settings are - # specified in this timezone. You should change the setting if it shows - # as "Invalid timezone" - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=timezone --set=America/Toronto - - # Guest login button - # You can hide or show the guest login button on the login page. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=guestloginbutton --set=0 - - # Analytics - # Analytics models, such as 'Students at risk of dropping out' or 'Upcoming activities due', - # can generate predictions, send insight notifications and offer further actions - # such as messaging users. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=enableanalytics --set=0 - - # Enable statistics - # If you choose 'yes' here, Moodle's cronjob will process the logs and gather some statistics. - # Depending on the amount of traffic on your site, this can take awhile. If you enable this, - # you will be able to see some interesting graphs and statistics about each of your courses, - # or on a sitewide basis. - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=enablestats --set=0 - - # Enable course recycle bin - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=coursebinenable --set=0 - - # Enable category recycle bin - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=categorybinenable --set=0 - - # Allow indexing by search engines - # This determines whether to allow search engines to index your site. "Everywhere" will allow - # the search engines to search everywhere including login and signup pages, which means sites - # with Force Login turned on are still indexed. To avoid the risk of spam involved with the - # signup page being searchable, use "Everywhere except login and signup pages". - # "Nowhere" will tell search engines not to index any page. Note this is only a tag in the - # header of the site. It is up to the search engine to respect the tag. - # 0 = Everywhere except login and signup pages - # 1 = Everywhere - # 2 = Nowhere - bin/moodle-docker-compose exec webserver php admin/cli/cfg.php --name=allowsearchengines --set=2 - - # Install xdebug extention in the new webserser. - # If already installed, the install will just fail. - bin/moodle-docker-compose exec webserver pecl install xdebug - - # Enable XDebug extension in Apache and restart the webserver container - bin/moodle-docker-compose exec webserver docker-php-ext-enable xdebug + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" || { + error_message "Failed to install Moodle for ${projectname}" + exit 1 + } + + # Upgrade Moodle to register the tool_excimer plugin. + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/upgrade.php --non-interactive || { + error_message "Failed to upgrade Moodle for ${projectname}" + exit 1 + } + info_message "Ran Moodle upgrade for ${projectname} to register tool_excimer plugin" + + # Enable the tool_excimer plugin. + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/cfg.php --component=tool_excimer --name=enable --set=1 || { + error_message "Failed to enable tool_excimer plugin for ${projectname}" + exit 1 + } + info_message "Enabled tool_excimer plugin for ${projectname}" + + # Install and enable XDebug extension. + bin/moodle-docker-compose exec webserver bash -c "pecl uninstall xdebug || true && pecl install xdebug && docker-php-ext-enable xdebug" || { + error_message "Failed to install XDebug for ${projectname}" + exit 1 + } bin/moodle-docker-compose restart webserver - - info_message "${folder} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" + info_message "Installed and enabled XDebug for ${projectname}" + + # Verify XDebug is loaded. + bin/moodle-docker-compose exec webserver php -i | grep -q xdebug && info_message "XDebug is loaded for ${projectname}" || { + error_message "XDebug failed to load for ${projectname}" + exit 1 + } + if [ "$DEBUG" = true ]; then + debug_message "XDebug configuration for ${projectname}:" + bin/moodle-docker-compose exec webserver php -i | grep -E 'xdebug\.(mode|client_host|client_port|log|log_level|idekey|discover_client_host)' + fi + + # Set Moodle configurations. + local configs=( + "sessioncookie=${projectname}" + "coursebinenable=0" + "backup_general_users=0 component=backup" + "updateautocheck=0" + "updatenotifybuilds=0" + "allowguestmymoodle=0" + "forcelogin=1" + "forceloginforprofiles=1" + "country=CA" + "defaultcity=Montreal" + "timezone=America/Toronto" + "guestloginbutton=0" + "enableanalytics=0" + "enablestats=0" + "categorybinenable=0" + "allowsearchengines=2" + ) + for config in "${configs[@]}"; do + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/cfg.php --name="${config%%=*}" --set="${config#*=}" || { + error_message "Failed to set config ${config%%=*} for ${projectname}" + exit 1 + } + done + info_message "${projectname} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" } -# This function resets all config files used during boot of project. -# Should be used when --destroy containers. reset_config_files() { - rm local.yml - git checkout assets/php/docker-php-ext-xdebug.ini + rm -f local.yml + git checkout assets/php/docker-php-ext-xdebug.ini || { + error_message "Failed to reset assets/php/docker-php-ext-xdebug.ini" + exit 1 + } + info_message "Reset configuration files" } exists_in_list() { LIST=$1 DELIMITER=$2 VALUE=$3 - LIST_WHITESPACES=`echo $LIST | tr "$DELIMITER" " "` + LIST_WHITESPACES=$(echo "$LIST" | tr "$DELIMITER" " ") for x in $LIST_WHITESPACES; do if [ "$x" = "$VALUE" ]; then return 1 @@ -255,16 +378,24 @@ if [ $# -eq 0 ]; then exit 1 fi -if [ $# -lt 1 ] || [ $# -gt 4 ]; then - error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments." +# Check for debug flag. +DEBUG=false +if [[ " $@ " =~ " --debug " ]]; then + DEBUG=true + debug_message "Debug mode enabled" +fi + +# Validate number of arguments (1-4, or 5 with --debug). +if [ $# -lt 1 ] || [ $# -gt 5 ]; then + error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments (or 5 with --debug)." help_messages exit 1 fi -# Validate the switch passed to the script. -list_of_options="--build --destroy --help --reboot --stop --start --restart" +# Validate the switch. +list_of_options="--build --destroy --help --restart --stop --start --debug" SWITCH=$1 -if exists_in_list "$list_of_options" " " $SWITCH; then +if exists_in_list "$list_of_options" " " "$SWITCH"; then error_message "Invalid option $SWITCH." help_messages exit 1 @@ -278,78 +409,83 @@ fi ######################## ### Global variables ### -# MOODLE_DOCKER_DB - database used by Moodle - default maria db -# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located; -# MOODLE_DOCKER_PORT - port (default 8000); -# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1; -# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites; +# MOODLE_DOCKER_DB - database used by Moodle - default maria db. +# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located. +# MOODLE_DOCKER_PORT - port (default 8000). +# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1. +# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites. # We always use Maria DB for all our Moodle. export MOODLE_DOCKER_DB=mariadb - -# Current working dir. -# Typically gives /home/username/projects. -cwd=$( dirname "$PWD" ) - -# Moodle Docker Port. -# AKA which port the webserver container will listen to. +cwd=$(dirname "$PWD") moodleDockerPort=(8000 1234 5678) - -# xDebug ports -# Each containers must have a their own port. -xdebugPort=(9003 9004 9005) +xDebugPort=(9003 9004 9005) # Use the multiple instances local.yml file. -cp local.yml_many local.yml +cp local.yml_many local.yml || { + error_message "Failed to copy local.yml_many to local.yml" + exit 1 +} +info_message "Copied local.yml_many to local.yml" ################################################ -### Process swithes that don't need options. ### +### Process switches that don't need options ### case $SWITCH in "--destroy") if ! docker ps | grep -q 'moodlehq'; then info_message "No containers running. Nothing to shutdown." - exit 1 + exit 0 fi - docker stop $(docker ps -a -q) - docker rm $(docker ps -a -q) + docker stop $(docker ps -a -q) || { + error_message "Failed to stop containers" + exit 1 + } + docker rm $(docker ps -a -q) || { + error_message "Failed to remove containers" + exit 1 + } reset_config_files info_message "All containers shut down and removed." - exit 1 + exit 0 ;; "--restart") if ! docker ps | grep -q 'moodlehq'; then - info_message "No containers running. Nothing to reboot." - exit 1 + info_message "No containers running. Nothing to restart." + exit 0 fi - docker restart $(docker ps -q) + docker restart $(docker ps -q) || { + error_message "Failed to restart containers" + exit 1 + } info_message "All sites restarted." - exit 1 + exit 0 ;; "--stop") if ! docker ps | grep -q 'moodlehq'; then info_message "No containers running. Nothing to stop." - exit 1 + exit 0 fi - docker stop $(docker ps -q) - # reset_config_files + docker stop $(docker ps -q) || { + error_message "Failed to stop containers" + exit 1 + } info_message "All sites stopped." - exit 1 + exit 0 ;; esac ############################################# -### Process swithes that require options. ### +### Process switches that require options ### # Ignore first parm passed to the script. # Skip the --switch to cycle the folders in argument. shift -iteratior=0 - -# Iterate the passed folders. -for i in "$@" -do - # Folder passed in args to the script. +iterator=0 +for i in "$@"; do + if [ "$i" = "--debug" ]; then + continue + fi argfolder="$i" # Full system path of the Moodle instance. @@ -357,42 +493,27 @@ do fullfolderpath="${cwd}/${argfolder}" export MOODLE_DOCKER_WWWROOT=${fullfolderpath} - # Check the Moodle version. If its 4.5 then set php version to 8.3. - export MOODLE_DOCKER_PHP_VERSION=8.1 - moodlever=$(grep "$branch = '405';" $fullfolderpath/version.php) - if [ "$moodlever" ]; then - export MOODLE_DOCKER_PHP_VERSION=8.3 - fi - # Used to name the project according to the folder name # which makes it easier to recognize who is who in Docker. projectname="${argfolder}" export COMPOSE_PROJECT_NAME=${projectname} + export MOODLE_DOCKER_WEB_PORT="${moodleDockerPort[$iterator]}" - # Set the port for the webserver. - export MOODLE_DOCKER_WEB_PORT="${moodleDockerPort[$iteratior]}" - - # Copy the config.php file to the Moodle folder. - cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php - + # Domain name for web server (defaults to localhost). + # export MOODLE_DOCKER_WEB_HOST="example.com" + case $SWITCH in "--build") - if [ -n "$(docker ps -f "name=${projectname}-webserver-1" -f "status=running" -q )" ]; then - error_message "The first site is already running! It cannot be re-initialized." + if [ -n "$(docker ps -f "name=${projectname}-webserver-1" -f "status=running" -q)" ]; then + error_message "The site ${projectname} is already running! It cannot be re-initialized." exit 1 fi - - # Build containers and install Moodle. - build_instances ${projectname} ${fullfolderpath} "${xdebugPort[$iteratior]}" + build_instances "${projectname}" "${fullfolderpath}" ;; "--start") - - # Start all Moodle instances. - start_instances ${projectname} "${xdebugPort[$iteratior]}" + start_instances "${projectname}" ;; esac - - # Increment loop counter. - iteratior=$((iteratior+1)) + iterator=$((iterator + 1)) done -exit 0 +exit 0 \ No newline at end of file