1033 lines
38 KiB
Bash
Executable File
1033 lines
38 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Copyright © 2021,2022 IsardVDI S.L.
|
|
#
|
|
# This file is part of DD
|
|
#
|
|
# DD is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or (at your
|
|
# option) any later version.
|
|
#
|
|
# DD 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 Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with DD. If not, see <https://www.gnu.org/licenses/>.
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
OPERATION="$1"
|
|
shift
|
|
|
|
# We need docker-compose >= 1.28 to catch configuration variables
|
|
REQUIRED_DOCKER_COMPOSE_VERSION="1.28"
|
|
|
|
docker_compose_version(){
|
|
docker-compose --version --short | sed 's/^docker-compose version \([^,]\+\),.*$/\1/'
|
|
}
|
|
|
|
check_docker_compose_version(){
|
|
# We cannot use sort -C because is not included in BusyBox v1.33.1 of docker:dind image
|
|
{
|
|
echo "$REQUIRED_DOCKER_COMPOSE_VERSION"
|
|
docker_compose_version
|
|
} | sort -c -V 2> /dev/null
|
|
}
|
|
|
|
get_os(){
|
|
if grep -q ^DISTRIB_ID=Ubuntu /etc/lsb-release 2>/dev/null; then
|
|
echo ubuntu
|
|
elif [ -f /etc/debian_version ]; then
|
|
echo debian
|
|
fi
|
|
}
|
|
|
|
help() {
|
|
cat <<-EOF
|
|
Example: ./dd.ctl [operation] [arguments]
|
|
|
|
For a new installation, you usually will want to run:
|
|
./dd-ctl prerequisites
|
|
./dd-ctl securize
|
|
./dd-ctl all
|
|
./dd-ctl saml
|
|
|
|
|
|
Generate adminer.yml to access DBs: ./dd-ctl adminer
|
|
Bring the current project up: ./dd-ctl all
|
|
Branding (custom/img, custom/menu): ./dd-ctl branding
|
|
Build the compose files: ./dd-ctl build
|
|
Build the devel compose files: ./dd-ctl build-devel
|
|
Apply customizations: ./dd-ctl customize
|
|
Stop the project when started: ./dd-ctl down
|
|
Show external files in repo, their license and source: ./dd-ctl listpatches
|
|
Generate .orig and .patch files to compare with upstream: ./dd-ctl genpatches
|
|
Rescan nextcloud data folders: ./dd-ctl nextcloud-scan
|
|
Install all prerequisites for installation: ./dd-ctl prerequisites
|
|
Update DD to latest version: ./dd-ctl update [branch-name] (defaults to main)
|
|
Restart api if changes applied (development): ./dd-ctl restart-api
|
|
Update SAML certificates: ./dd-ctl saml
|
|
Set secure passwords in dd.conf: ./dd-ctl securize
|
|
Set a config variable in dd.conf: ./dd-ctl setconf VARIABLE [VALUE]
|
|
Start the project when stopped: ./dd-ctl up
|
|
Upgrade plugins: ./dd-ctl upgrade-plugins
|
|
Regenerate docker-compose.yml from conf: ./dd-ctl yml
|
|
EOF
|
|
}
|
|
|
|
# Help messages
|
|
if [ -z "$OPERATION" ] || [ "$OPERATION" = "-h" ] || [ "$OPERATION" = "--help" ]; then
|
|
test -n "$OPERATION" || printf "Missing command.\n\n"
|
|
help
|
|
exit
|
|
fi
|
|
|
|
# Sanity checks
|
|
if [ -z "$(get_os)" ]; then
|
|
cat >&2 <<-EOF
|
|
*****************************************************************
|
|
Your OS doesn't seem to be Debian or Ubuntu and is not supported!
|
|
Things might still work, please report back.
|
|
*****************************************************************
|
|
EOF
|
|
fi
|
|
if [ "$OPERATION" != "prerequisites" ]; then
|
|
if [ ! -d "custom" ]; then
|
|
echo "You need to copy custom.sample to custom folder and adapt it to your needs." >&2
|
|
exit 1
|
|
fi
|
|
if [ ! -f "dd.conf" ]; then
|
|
echo "You need to copy dd.conf.sample to dd.conf and adapt" >&2
|
|
exit 1
|
|
fi
|
|
if ! check_docker_compose_version; then
|
|
echo "ERROR: Please use docker-compose greather than or equal to $REQUIRED_DOCKER_COMPOSE_VERSION." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
REPO_BRANCH="${1:-main}"
|
|
|
|
|
|
cp dd.conf .env
|
|
CUSTOM_PATH=$(pwd)
|
|
. ./.env
|
|
|
|
prerequisites_docker(){
|
|
# Remove uncompatible docker packages
|
|
for pkg in docker docker-engine docker.io containerd runc; do
|
|
if dpkg -s "${pkg}" >/dev/null; then
|
|
apt-get remove -y "${pkg}"
|
|
fi
|
|
done
|
|
|
|
# Install upstream-docker repo pre-requisites
|
|
apt-get install -y \
|
|
apt-transport-https \
|
|
ca-certificates \
|
|
curl \
|
|
gnupg-agent \
|
|
software-properties-common \
|
|
git \
|
|
unzip \
|
|
libffi-dev
|
|
|
|
os="$(get_os)"
|
|
curl -fsSL "https://download.docker.com/linux/${os:?}/gpg" | \
|
|
apt-key add -
|
|
add-apt-repository \
|
|
"deb [arch=amd64] https://download.docker.com/linux/${os:?} \
|
|
$(lsb_release -cs) \
|
|
stable"
|
|
apt-get update -y
|
|
# docker-ce must be used instead of the one from the distro
|
|
apt-get install -y docker-ce docker-ce-cli containerd.io
|
|
|
|
apt-get install -y python3-pip
|
|
# docker-compose > 1.28 is required, latest will be installed
|
|
pip3 install docker-compose
|
|
}
|
|
prerequisites_pwd(){
|
|
apt-get install -y dictionaries-common wamerican
|
|
}
|
|
|
|
ddupdate(){
|
|
# Bring down services
|
|
./dd-ctl down
|
|
# Switch to latest version
|
|
git fetch && git checkout "$REPO_BRANCH"
|
|
git pull --rebase --autostash
|
|
# Needed for dd-apps submodules...
|
|
git submodule update --init --recursive
|
|
case "${1}" in
|
|
--full)
|
|
# Rebuild containers
|
|
./dd-ctl build
|
|
# Upgrade plugins
|
|
./dd-ctl upgrade-plugins
|
|
# Reapply customisations if needed
|
|
./dd-ctl customize
|
|
;;
|
|
esac
|
|
}
|
|
|
|
build_compose(){
|
|
DD_DEFAULT_BUILD="$(git rev-parse --short HEAD)"
|
|
export DD_BUILD="${DD_BUILD:-${DD_DEFAULT_BUILD}}"
|
|
setconf DD_BUILD "${DD_BUILD}" .env
|
|
|
|
setconf CUSTOM_PATH "$CUSTOM_PATH" .env
|
|
setconf BUILD_APPS_ROOT_PATH "$CUSTOM_PATH/dd-apps" .env
|
|
setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .env
|
|
setconf BUILD_WAF_ROOT_PATH "$CUSTOM_PATH/dd-waf" .env
|
|
## Prepare apps environment
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/.env
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/postgresql && \
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/mariadb && \
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/moodle && \
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/nextcloud && \
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/wordpress && \
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/etherpad
|
|
|
|
## Prepare sso environment
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-sso/.env
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-sso/docker-compose-parts/.env
|
|
|
|
## Prepare waf environment
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-waf/.env
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-waf/docker-compose-parts/.env
|
|
|
|
# Clean up older custom data
|
|
rm -rf custom/system/keycloak-themes
|
|
rmdir custom/system 2>/dev/null || true
|
|
|
|
if [ "$BEHIND_PROXY" = "true" ]; then
|
|
BEHIND="haproxy-behind.yml"
|
|
MODSECURITY="-f dd-waf/docker-compose-parts/modsecurity.yml"
|
|
HAPROXY_WAF="-f dd-waf/docker-compose-parts/haproxy.yml"
|
|
else
|
|
BEHIND="haproxy.yml"
|
|
fi
|
|
|
|
# Build compose ymls
|
|
# shellcheck disable=SC2086
|
|
docker-compose \
|
|
$MODSECURITY $HAPROXY_WAF \
|
|
\
|
|
-f dd-sso/docker-compose-parts/$BEHIND \
|
|
-f dd-sso/docker-compose-parts/api.yml \
|
|
-f dd-sso/docker-compose-parts/keycloak.yml \
|
|
-f dd-sso/docker-compose-parts/avatars.yml \
|
|
-f dd-apps/docker/postgresql/postgresql.yml \
|
|
-f dd-sso/docker-compose-parts/admin.yml \
|
|
\
|
|
-f dd-apps/docker/moodle/moodle.yml \
|
|
-f dd-apps/docker/nextcloud/nextcloud.yml \
|
|
-f dd-apps/docker/wordpress/wordpress.yml \
|
|
-f dd-apps/docker/etherpad/etherpad.yml \
|
|
-f dd-apps/docker/onlyoffice/onlyoffice.yml \
|
|
-f dd-apps/docker/redis/redis.yml \
|
|
-f dd-apps/docker/postgresql/postgresql.yml \
|
|
-f dd-apps/docker/mariadb/mariadb.yml \
|
|
-f dd-apps/docker/network.yml \
|
|
config > docker-compose.yml
|
|
}
|
|
|
|
listpatches(){
|
|
cat <<-EOM
|
|
# Generate .orig and .patch files with ./dd-ctl genpatches
|
|
# file license author url
|
|
EOM
|
|
# shellcheck disable=SC2044 # TODO: Get rid of this for X in find
|
|
for patchfile in $(find . -name 'dd-patch'); do
|
|
patchdir="$(dirname "${patchfile}")"
|
|
grep -vE '^#' "${patchfile}" | awk "{print \"${patchdir}/\" \$0}"
|
|
done
|
|
}
|
|
|
|
genpatches(){
|
|
CD="$(pwd)"
|
|
# shellcheck disable=SC2044 # TODO: Get rid of this for X in find
|
|
for patchfile in $(find . -name 'dd-patch'); do
|
|
# shellcheck disable=SC2164 # We got the dir from find
|
|
cd "$(dirname "${patchfile}")"
|
|
echo "IN DIR $(pwd)"
|
|
grep -vE '^#' dd-patch | while IFS= read -r line; do
|
|
fn="$(echo "${line}" | cut -f 1)"
|
|
url="$(echo "${line}" | cut -f 4)"
|
|
wget "${url}" -O "${fn}.orig"
|
|
diff "${fn}.orig" "${fn}" > "${fn}.patch"
|
|
done
|
|
# shellcheck disable=SC2164 # This was previous working dir
|
|
cd "${CD}"
|
|
done
|
|
}
|
|
|
|
build(){
|
|
build_compose
|
|
docker-compose build --pull
|
|
}
|
|
|
|
build_compose_develop(){
|
|
build_compose
|
|
|
|
## Prepare sso environment
|
|
setconf CUSTOM_PATH "$CUSTOM_PATH" .env
|
|
setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .env
|
|
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-sso/.env
|
|
ln -sf "${CUSTOM_PATH}/.env" dd-sso/docker-compose-parts/.env
|
|
|
|
docker-compose -f docker-compose.yml \
|
|
-f dd-sso/docker-compose-parts/api.devel.yml \
|
|
-f dd-sso/docker-compose-parts/admin.devel.yml \
|
|
config > devel.yml
|
|
}
|
|
|
|
up(){
|
|
docker-compose up -d
|
|
}
|
|
|
|
down(){
|
|
docker-compose down
|
|
}
|
|
|
|
setup_nextcloud(){
|
|
echo " --> Applying custom settings in nextcloud"
|
|
# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=$DDADMIN_PASSWORD && php occ user:add --password-from-env --display-name="DD Admin" --group="admin" $DDADMIN_USER'
|
|
|
|
# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=admin && php occ user:delete admin'
|
|
# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=LostAdminGroup && php occ user:add --password-from-env --display-name="Admin" --group="admin" admin'
|
|
|
|
# docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:app:set unaprova token --value "SuperS3cret"
|
|
|
|
#cp -R $BUILD_APPS_ROOT_PATH/dd-apps/docker/nextcloud/themes/* $DATA_FOLDER/nextcloud/themes/
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set default_language --value="ca"
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set skeletondirectory --value=''
|
|
|
|
# Disable certain NextCloud apps
|
|
for app in firstrunwizard recommendations dashboard; do
|
|
docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
|
|
php occ --no-warnings app:disable "${app}"
|
|
EOF
|
|
done
|
|
|
|
# Install and enable NextCloud apps
|
|
for app in bruteforcesettings polls calendar spreed bbb mail ownpad onlyoffice; do
|
|
docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
|
|
php occ --no-warnings app:install "${app}"
|
|
php occ --no-warnings app:enable "${app}"
|
|
EOF
|
|
done
|
|
# Disable in Nextcloud
|
|
# shellcheck disable=SC2043 # We currently only force-disable one app
|
|
for app in circles; do
|
|
docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
|
|
php occ --no-warnings app:disable "${app}" || true
|
|
EOF
|
|
done
|
|
|
|
# Temporary patch while upstream lands our changes
|
|
# See: https://github.com/nextcloud/mail/pull/6908
|
|
for f in appinfo/info.xml lib/Command/UpdateAccount.php lib/Db/MailAccountMapper.php; do
|
|
install -m 0644 -o 82 -g 82 "dd-apps/docker/nextcloud/nc_mail/$f" "${SRC_FOLDER}/nextcloud/custom_apps/mail/$f"
|
|
done
|
|
|
|
# Custom forms
|
|
docker exec dd-apps-nextcloud-app apk add git npm composer
|
|
docker exec -u www-data dd-apps-nextcloud-app rm -rf /var/www/html/custom_apps/forms
|
|
docker exec -u www-data dd-apps-nextcloud-app git clone https://github.com/juanan3ip/form -b dev /var/www/html/custom_apps/forms
|
|
docker exec -u www-data dd-apps-nextcloud-app npm --prefix /var/www/html/custom_apps/forms install
|
|
docker exec -u www-data dd-apps-nextcloud-app composer -d/var/www/html/custom_apps/forms install --no-dev -o
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ app:enable forms
|
|
|
|
# Disable Big Blue Button media check by default
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set bbb join.mediaCheck --value="false"
|
|
# Disable Big Blue Button listen only mode by default
|
|
docker exec dd-apps-nextcloud-app sed -i.orig 's/^\(\s*$room->setListenOnly(\)true\();\)$/\1false\2/' /var/www/html/custom_apps/bbb/lib/Service/RoomService.php
|
|
# Enable option to join muted to Big Blue Button room by default
|
|
docker exec dd-apps-nextcloud-app sed -i 's/^\(\s*$room->setJoinMuted(\)false\();\)$/\1true\2/' /var/www/html/custom_apps/bbb/lib/Service/RoomService.php
|
|
# Remove meeting join nextcloud bbb app dialog exclamation marks
|
|
docker exec dd-apps-nextcloud-app sh -c "sed -i.orig 's/\(^\s*\"Please enter your name!\" : [^¡]*\)¡\?\([^!]*\)!\(.*\)$/\1\2\3/' /var/www/html/custom_apps/bbb/l10n/*.json"
|
|
docker exec dd-apps-nextcloud-app sh -c "sed -i 's/\(^\s*\"Let\x27s go!\" : [^¡]*\)¡\?\([^!]*\)!\(.*\)$/\1\2\3/' /var/www/html/custom_apps/bbb/l10n/*.json"
|
|
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set theme --value=dd
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set allow_local_remote_servers --value=true
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings maintenance:theme:update
|
|
|
|
#docker exec -u www-data dd-apps-nextcloud-app php occ app:install user_saml
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ app:enable user_saml
|
|
docker exec dd-apps-nextcloud-app apk add jq
|
|
docker exec dd-apps-nextcloud-app sh -c 'jq ". + {\"pad\": [\"application/x-ownpad\"], \"calc\": [\"application/x-ownpad\"]}" /var/www/html/resources/config/mimetypemapping.dist.json > /var/www/html/config/mimetypemapping.json'
|
|
nextcloud_scan
|
|
# Open pads in a new tab/window
|
|
docker exec dd-apps-nextcloud-app sed -i.orig 's/^\(\s*\)\(var viewer = OC.generateUrl.*\)/\1\2\n\1window.open(viewer);\n\1return;/' /var/www/html/custom_apps/ownpad/js/ownpad.js
|
|
|
|
# SMTP
|
|
SMTP_LOCAL_PART="$(echo "${SMTP_USER}" | cut -d '@' -f 1)"
|
|
SMTP_DOMAIN="$(echo "${SMTP_USER}" | cut -d '@' -f 2)"
|
|
docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
|
|
php occ --no-warnings config:system:set -n mail_smtpmode --value="smtp"
|
|
php occ --no-warnings config:system:set -n mail_smtpsecure --value="${SMTP_PROTOCOL}"
|
|
php occ --no-warnings config:system:set -n mail_sendmailmode --value="smtp"
|
|
php occ --no-warnings config:system:set -n mail_from_address --value="${SMTP_LOCAL_PART}"
|
|
php occ --no-warnings config:system:set -n mail_domain --value="${SMTP_DOMAIN}"
|
|
php occ --no-warnings config:system:set -n mail_smtpauth --value=1
|
|
php occ --no-warnings config:system:set -n mail_smtpauthtype --value="LOGIN"
|
|
php occ --no-warnings config:system:set -n mail_smtphost --value="${SMTP_HOST}"
|
|
php occ --no-warnings config:system:set -n mail_smtpport --value="${SMTP_PORT}"
|
|
php occ --no-warnings config:system:set -n mail_smtpname --value="${SMTP_USER}"
|
|
echo 'Setting Nextcloud password'
|
|
php occ --no-warnings config:system:set -n -q mail_smtppassword --value="${SMTP_PASSWORD}"
|
|
EOF
|
|
|
|
# Settings
|
|
docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
|
|
php occ --no-warnings config:app:set -n ownpad ownpad_etherpad_enable --value="yes"
|
|
php occ --no-warnings config:app:set -n ownpad ownpad_etherpad_host --value="https://pad.$DOMAIN"
|
|
|
|
php occ --no-warnings config:app:set -n onlyoffice DocumentServerUrl --value="https://oof.$DOMAIN"
|
|
php occ --no-warnings config:app:set -n onlyoffice jwt_secret --value="secret"
|
|
php occ --no-warnings config:app:set -n onlyoffice jwt_header --value="Authorization"
|
|
php occ --no-warnings config:app:set -n onlyoffice sameTab --value="false"
|
|
|
|
# Moodle nextcloud task needs forcesave onlyoffice option
|
|
php occ --no-warnings config:app:set -n onlyoffice customizationForcesave --value="true"
|
|
|
|
# Add allow list IPs
|
|
php occ --no-warnings config:app:set -n bruteForce whitelist_1 --value='172.16.0.0/12'
|
|
|
|
# OnlyOffice
|
|
php occ --no-warnings config:app:set -n onlyoffice preview --value="true"
|
|
php occ --no-warnings config:app:set -n onlyoffice defFormats --value="{\"csv\":\"false\",\"doc\":\"true\",\"docm\":\"false\",\"docx\":\"true\",\"docxf\":\"true\",\"oform\":\"true\",\"dotx\":\"false\",\"epub\":\"false\",\"html\":\"false\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"otp\":\"true\",\"ots\":\"true\",\"ott\":\"true\",\"pdf\":\"false\",\"potm\":\"false\",\"potx\":\"false\",\"ppsm\":\"false\",\"ppsx\":\"true\",\"ppt\":\"true\",\"pptm\":\"false\",\"pptx\":\"true\",\"rtf\":\"false\",\"txt\":\"false\",\"xls\":\"true\",\"xlsm\":\"false\",\"xlsx\":\"true\",\"xltm\":\"false\",\"xltx\":\"true\"}",
|
|
php occ --no-warnings config:app:set -n onlyoffice editFormats --value="{\"csv\":\"true\",\"odp\":\"false\",\"ods\":\"false\",\"odt\":\"false\",\"rtf\":\"false\",\"txt\":\"true\"}"
|
|
|
|
EOF
|
|
|
|
# Allow nextcloud into other apps iframes
|
|
# Content-Security-Policy: frame-ancestors 'self' *.$DOMAIN;
|
|
docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedFrameAncestors = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php
|
|
|
|
# Content-Sety-Policy: connect-src 'self -' *.$DOMAIN;
|
|
docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedConnectDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php
|
|
|
|
# Content-Sety-Policy: img-src 'self' *. -$DOMAIN;
|
|
docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedImageDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php
|
|
|
|
# Content-Sety-Policy: style-src 'self' -*.$DOMAIN;
|
|
docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedStyleDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php
|
|
|
|
# Content-Sety-Policy: font-src 'self' * -.$DOMAIN;
|
|
docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedFontDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php
|
|
|
|
# Fix nextcloud files_external "segudos" typo
|
|
# https://github.com/nextcloud/server/pull/28990
|
|
docker exec dd-apps-nextcloud-app sh -c 'sed -i.orig -e "s/segudos/segundos/" /var/www/html/apps/files_external/l10n/es_*.js'
|
|
|
|
# Import fix from Nextcloud 22 of pdf viewer
|
|
# https://github.com/nextcloud/files_pdfviewer/issues/381#issuecomment-845806364
|
|
docker exec dd-apps-nextcloud-app sed -i 's/encodeURIComponent(i\[a\])/i[a]/' /var/www/html/apps/files_pdfviewer/js/files_pdfviewer-main.js
|
|
|
|
# Add default file for moodle activities
|
|
if [ ! -f "$DATA_FOLDER/nextcloud/admin/files/template.docx" ]; then
|
|
cp dd-apps/docker/nextcloud/template.docx "$DATA_FOLDER/nextcloud/admin/files/"
|
|
nextcloud_scan
|
|
fi
|
|
|
|
configure_nextcloud_logo
|
|
|
|
nextcloud_upgrade
|
|
}
|
|
|
|
nextcloud_upgrade(){
|
|
docker-compose exec -u www-data dd-apps-nextcloud-app ./occ upgrade
|
|
}
|
|
|
|
nextcloud_scan(){
|
|
# The folders shown as 'not writeable' are empty user folders. Not a problem.
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ files:scan --all
|
|
}
|
|
|
|
setup_moodle(){
|
|
echo " --> Applying custom settings in moodle"
|
|
# TODO: check why admin/cli/cfg can't be read with -u nobody
|
|
docker exec -i dd-apps-moodle sh -s <<-EOF
|
|
php7 admin/cli/cfg.php --name=guestloginbutton --set=0
|
|
php7 admin/cli/cfg.php --name=enrol_plugins_enabled --set=manual
|
|
php7 admin/cli/cfg.php --name=enablemobilewebservice --set=0
|
|
php7 admin/cli/cfg.php --name=enablebadges --set=0
|
|
php7 admin/cli/cfg.php --name=timezone --set="${MOODLE_TIMEZONE-Europe/Madrid}"
|
|
php7 admin/cli/purge_caches.php
|
|
EOF
|
|
}
|
|
|
|
setup_wordpress(){
|
|
echo " --> Applying custom settings in wordpress"
|
|
chown -R 33:33 "${DATA_FOLDER}/wordpress"
|
|
docker exec -i --user=33 dd-apps-wordpress sh -s <<-EOF
|
|
wp core install --path="/var/www/html" \
|
|
--url=wp.${DOMAIN} --title="${TITLE}" \
|
|
--admin_user=${WORDPRESS_ADMIN_USER} \
|
|
--admin_password=${WORDPRESS_ADMIN_PASSWORD} \
|
|
--admin_email=${SMTP_USER}
|
|
wp core multisite-convert
|
|
|
|
wp plugin activate onelogin-saml-sso
|
|
wp plugin install generateblocks --activate
|
|
wp plugin activate generateblocks --network
|
|
|
|
wp theme install generatepress --activate
|
|
wp theme enable generatepress --network
|
|
wp theme delete twentynineteen
|
|
wp theme delete twentytwenty
|
|
wp theme delete twentytwentyone
|
|
|
|
wp option set WPLANG ca
|
|
wp option set date_format "d/m/Y"
|
|
EOF
|
|
}
|
|
|
|
setup_keycloak(){
|
|
echo " --> Setting up SAML: Keycloak realm and client_scopes"
|
|
docker exec -i dd-sso-admin sh -s <<-EOF
|
|
export PYTHONWARNINGS='ignore:Unverified HTTPS request'
|
|
cd /admin/saml_scripts/ && python3 keycloak_config.py
|
|
EOF
|
|
}
|
|
|
|
saml_generate_certificates(){
|
|
saml_dir="${DATA_FOLDER}/saml"
|
|
mkdir -p "${saml_dir}/public"
|
|
|
|
# Moodle generates its own certificate earlier, only NC and Wp
|
|
for saml_info in nextcloud:82 wordpress:33; do
|
|
saml_sp="$(echo "${saml_info}" | cut -d ':' -f 1)"
|
|
sp_uid="$(echo "${saml_info}" | cut -d ':' -f 2)"
|
|
sp_dir="${saml_dir}/${saml_sp}"
|
|
mkdir -p "${sp_dir}"
|
|
C=CA
|
|
L=Barcelona
|
|
O=localdomain
|
|
CN_CA=$O
|
|
# Generate certificate
|
|
echo " --> Generating SAML certificates for SP: ${saml_sp}"
|
|
openssl req -nodes -new -x509 \
|
|
-keyout "${sp_dir}/private.key" \
|
|
-out "${sp_dir}/public.crt" \
|
|
-subj "/C=$C/L=$L/O=$O/CN=$CN_CA" -days 3650
|
|
# Fix permissions
|
|
chown -R "${sp_uid}:${sp_uid}" "${sp_dir}"
|
|
chmod 0550 "${sp_dir}"
|
|
# Propagate public part
|
|
cp "${sp_dir}/public.crt" "${saml_dir}/public/${saml_sp}.crt"
|
|
done
|
|
# TODO: Rework wordpress_saml.py so we can get rid of this
|
|
cp "${saml_dir}/wordpress/private.key" "${saml_dir}/public/wordpress.key"
|
|
|
|
chmod 0555 "${saml_dir}/public"
|
|
find "${saml_dir}/public" -type f -exec chmod 0444 '{}' '+'
|
|
}
|
|
|
|
saml_register_sps_with_idp(){
|
|
wait_for_moodle
|
|
|
|
# Setup SAML for each SP
|
|
for saml_sp in moodle nextcloud wordpress email; do
|
|
echo " --> Registering SAML SP '${saml_sp}' in IDP"
|
|
docker exec -i dd-sso-admin sh -s <<-EOF
|
|
export PYTHONWARNINGS='ignore:Unverified HTTPS request'
|
|
cd /admin/saml_scripts/ && python3 ${saml_sp}_saml.py
|
|
EOF
|
|
test $? == 0 || printf "\tError setting up SAML for %s...\n" "${saml_sp}" >&2
|
|
done
|
|
|
|
# Purge cache for moodle
|
|
docker exec -i dd-apps-moodle php7 admin/cli/purge_caches.php
|
|
}
|
|
|
|
saml_setup_idp_in_sps(){
|
|
# We need to support this for newer Nextcloud versions
|
|
saml_info="dd-apps-nextcloud-app:82"
|
|
saml_sp="$(echo "${saml_info}" | cut -d ':' -f 1)"
|
|
sp_uid="$(echo "${saml_info}" | cut -d ':' -f 2)"
|
|
echo " --> Setting up SAML IDP in ${saml_sp}"
|
|
docker exec -i -u "${sp_uid}" "${saml_sp}" /saml.sh
|
|
}
|
|
|
|
saml(){
|
|
if [ "${1:-}" != "--no-up" ]; then
|
|
up
|
|
wait_for_moodle
|
|
fi
|
|
# Ensure realm is OK and write public IDP cert
|
|
setup_keycloak
|
|
# Make sure each SP has its own certs and fix permissions if needed
|
|
saml_generate_certificates
|
|
# Register all SPs with the IDP
|
|
saml_register_sps_with_idp
|
|
# Setup IDP in each SP
|
|
saml_setup_idp_in_sps
|
|
}
|
|
|
|
wait_for_moodle(){
|
|
echo "Waiting for system to be fully up before customizing... It can take some minutes..."
|
|
echo " (you can monitorize install with: docker logs dd-apps-moodle --follow"
|
|
# This previously waited for the container to be 'healthy',
|
|
# but that was not what is actually required here, which is:
|
|
# - Is moodle installed?
|
|
# - Is the web service up?
|
|
# That is now checked in /is_moodle_ready.sh
|
|
while ! docker exec dd-apps-moodle /is_moodle_ready.sh; do
|
|
sleep 2;
|
|
done
|
|
}
|
|
|
|
upgrade_moodle(){
|
|
docker exec -i dd-apps-moodle php7 admin/cli/maintenance.php --enable
|
|
docker exec -i dd-apps-moodle php7 admin/cli/upgrade.php --non-interactive --allow-unstable
|
|
docker exec -i dd-apps-moodle php7 admin/cli/maintenance.php --disable
|
|
}
|
|
|
|
extras_adminer(){
|
|
docker-compose -f dd-apps/docker/network.yml \
|
|
-f dd-sso/docker-compose-parts/adminer.yml config > adminer.yml
|
|
echo " --> Generated adminer.yml"
|
|
echo " Bring it up: docker-compose -f adminer.yml up -d"
|
|
echo " Connect to: https://sso.$DOMAIN/dd-sso-adminer/"
|
|
echo " Parameters:"
|
|
echo " - System: PostgreSQL (or Mysql for wordpress db)"
|
|
echo " Server: dd-apps-postgresql (or dd-apps-mariadb for wordpress db)"
|
|
echo " User/Pass/Database from dd.conf"
|
|
}
|
|
|
|
extras_pgtuner(){
|
|
docker-compose -f dd-apps/docker/network.yml \
|
|
-f dd-sso/docker-compose-parts/pgtuner.yml config > pgtuner.yml
|
|
echo " --> Generated pgtuner.yml"
|
|
}
|
|
|
|
extras_nextcloud_remove_banned_ips(){
|
|
docker-compose exec dd-apps-postgresql psql -v ON_ERROR_STOP=1 \
|
|
-U admin nextcloud -c "DELETE FROM oc_bruteforce_attempts;"
|
|
}
|
|
|
|
extras_nextcloud_set_admin_group(){
|
|
docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=admin && php occ user:delete admin'
|
|
docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=N3xtcl0ud && php occ user:add --password-from-env --display-name="Admin" --group="admin" admin'
|
|
}
|
|
|
|
extras_dump_keycloak_client(){
|
|
docker exec -i dd-sso-keycloak sh -s <<-EOF
|
|
/opt/jboss/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password keycloakkeycloak \
|
|
&& /opt/jboss/keycloak/bin/kcadm.sh get clients/bef873f0-2079-4876-8657-067de27d01b7 -r master
|
|
EOF
|
|
}
|
|
upgrade_plugins_moodle(){
|
|
wait_for_moodle
|
|
rm -rf /tmp/moodle
|
|
|
|
mkdir -p /tmp/moodle/mod
|
|
mkdir -p /tmp/moodle/mod/assign/submission
|
|
mkdir -p /tmp/moodle/auth/saml2
|
|
mkdir -p /tmp/moodle/theme/cbe
|
|
mkdir -p /tmp/moodle/blocks
|
|
mkdir -p /tmp/moodle/lib/editor/atto/plugins/tipnc
|
|
|
|
curl --location "${MOODLE_PLUGIN_JITSI_OVERRIDE:-https://moodle.org/plugins/download.php/27002/mod_jitsi_moodle40_2022070602.zip}" > jitsi.zip
|
|
unzip -q jitsi.zip -d /tmp/moodle/mod/
|
|
rm jitsi.zip
|
|
|
|
curl --location "${MOODLE_PLUGIN_BBB_OVERRIDE:-https://moodle.org/plugins/download.php/26792/mod_bigbluebuttonbn_moodle311_2019101014.zip}" > bbb.zip
|
|
unzip -q bbb.zip -d /tmp/moodle/mod/
|
|
rm bbb.zip
|
|
|
|
# curl --location https://github.com/isard-vdi/moodle-auth_saml2/archive/refs/heads/role_map.zip > auth_saml2.zip
|
|
# curl --location https://moodle.org/plugins/download.php/24556/auth_saml2_moodle311_2021062900.zip > auth_saml2.zip
|
|
curl --location "${MOODLE_PLUGIN_SAML_OVERRIDE:-https://github.com/isard-vdi/moodle-auth_saml2/archive/refs/heads/role_map.zip}" > auth_saml2.zip
|
|
unzip -q auth_saml2.zip -d /tmp/moodle/auth/
|
|
mv /tmp/moodle/auth/moodle-auth_saml2-role_map/* /tmp/moodle/auth/saml2/
|
|
rm -rf /tmp/moodle/auth/moodle-auth_saml2-role_map
|
|
rm auth_saml2.zip
|
|
M3IPSHARE="https://github.com/3iPunt/moodle_mod_tresipuntshare/archive/refs/heads/master.zip"
|
|
|
|
if [[ "${MOODLE_PLUGIN_TRESIPUNTSHARE_OVERRIDE:-${M3IPSHARE}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
curl --location "${MOODLE_PLUGIN_TRESIPUNTSHARE_OVERRIDE:-${M3IPSHARE}}" > tresipuntshare.zip
|
|
unzip -q tresipuntshare.zip -d /tmp/moodle/mod/
|
|
mv /tmp/moodle/mod/moodle_mod_tresipuntshare-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntshare
|
|
rm tresipuntshare.zip
|
|
M3IPVIDEO="https://github.com/3iPunt/moodle_mod_tresipuntvideo/archive/refs/heads/master.zip"
|
|
|
|
if [[ "${MOODLE_PLUGIN_TRESIPUNTVIDEO_OVERRIDE:-${M3IPVIDEO}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
curl --location "${MOODLE_PLUGIN_TRESIPUNTVIDEO_OVERRIDE:-${M3IPVIDEO}}" > tresipuntvideo.zip
|
|
unzip -q tresipuntvideo.zip -d /tmp/moodle/mod/
|
|
mv /tmp/moodle/mod/moodle_mod_tresipuntvideo-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntvideo
|
|
rm tresipuntvideo.zip
|
|
M3IPAUDIO="https://github.com/3iPunt/moodle_mod_tresipuntaudio/archive/refs/heads/master.zip"
|
|
|
|
if [[ "${MOODLE_PLUGIN_TRESIPUNTAUDIO_OVERRIDE:-${M3IPAUDIO}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
curl --location "${MOODLE_PLUGIN_TRESIPUNTAUDIO_OVERRIDE:-${M3IPAUDIO}}" > tresipuntaudio.zip
|
|
unzip -q tresipuntaudio.zip -d /tmp/moodle/mod/
|
|
mv /tmp/moodle/mod/moodle_mod_tresipuntaudio-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntaudio
|
|
rm tresipuntaudio.zip
|
|
M3IPSUBMISSION="https://github.com/3iPunt/moodle_assignsubmission_tipnc/archive/refs/heads/master.zip"
|
|
|
|
if [[ "${MOODLE_PLUGIN_ASSIGNSUBMISSION_OVERRIDE:-${M3IPSUBMISSION}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
curl --location "${MOODLE_PLUGIN_ASSIGNSUBMISSION_OVERRIDE:-${M3IPSUBMISSION}}" > assignsubmission_tipnc.zip
|
|
unzip -q assignsubmission_tipnc.zip -d /tmp/moodle/mod/assign/submission/
|
|
mv /tmp/moodle/mod/assign/submission/moodle_assignsubmission_tipnc-$PLUGIN_BRANCH /tmp/moodle/mod/assign/submission/tipnc
|
|
rm assignsubmission_tipnc.zip
|
|
M3IPSPEND="https://github.com/3iPunt/moodle_block_tresipuntmodspend/archive/refs/heads/master.zip"
|
|
|
|
curl --location "${MOODLE_PLUGIN_TRESIPUNTMODSPEND_OVERRIDE:-${M3IPSPEND}}" > block_tresipuntmodspend.zip
|
|
unzip -q block_tresipuntmodspend.zip -d /tmp/moodle/blocks/
|
|
rm block_tresipuntmodspend.zip
|
|
M3IPCBE="https://github.com/3iPunt/moodle_theme_cbe/archive/refs/heads/master.zip"
|
|
|
|
if [[ "${MOODLE_THEME_CBE_OVERRIDE:-${M3IPCBE}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
curl --location "${MOODLE_THEME_CBE_OVERRIDE:-${M3IPCBE}}" > tresipunt_theme_cbe.zip
|
|
unzip -q tresipunt_theme_cbe.zip -d /tmp/moodle/theme/cbe/
|
|
mv /tmp/moodle/theme/cbe/moodle_theme_cbe-$PLUGIN_BRANCH/* /tmp/moodle/theme/cbe/
|
|
rm tresipunt_theme_cbe.zip
|
|
|
|
# mod_tipnextcloud
|
|
M3IPTN="https://github.com/3iPunt/mod_tipnextcloud/archive/refs/heads/master.zip"
|
|
if [[ "${MOODLE_MOD_TN_OVERRIDE:-${M3IPTN}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
|
|
curl --location "${MOODLE_MOD_TN_OVERRIDE:-${M3IPTN}}" > tresipunt_mod_tn.zip
|
|
unzip -q tresipunt_mod_tn.zip -d /tmp/moodle/mod/tipnextcloud/
|
|
mv /tmp/moodle/mod/tipnextcloud/mod_tipnextcloud-$PLUGIN_BRANCH/* /tmp/moodle/mod/tipnextcloud/
|
|
rm tresipunt_mod_tn.zip
|
|
|
|
|
|
# atto_tipnc https://github.com/3iPunt/atto_tipnc
|
|
M3ATTOTIPTN="https://github.com/3iPunt/atto_tipnc/archive/refs/heads/master.zip"
|
|
if [[ "${MOODLE_ATTOTIPTN_OVERRIDE:-${M3ATTOTIPTN}}" == *"develop"* ]]; then
|
|
PLUGIN_BRANCH=develop
|
|
else
|
|
PLUGIN_BRANCH=master
|
|
fi
|
|
|
|
curl --location "${MOODLE_ATTOTIPTN_OVERRIDE:-https://github.com/3iPunt/atto_tipnc/archive/refs/heads/master.zip}" > tresipunt_atto_tipnc.zip
|
|
unzip -q tresipunt_atto_tipnc.zip -d /tmp/moodle/lib/editor/atto/plugins/tipnc/
|
|
mv /tmp/moodle/lib/editor/atto/plugins/tipnc/atto_tipnc-$PLUGIN_BRANCH/* /tmp/moodle/lib/editor/atto/plugins/tipnc/
|
|
rm tresipunt_atto_tipnc.zip
|
|
|
|
# local_mail
|
|
curl --location "${MOODLE_PLUGIN_MAIL_OVERRIDE:-https://moodle.org/plugins/download.php/26393/local_mail_moodle40_2017121407.zip}" > mail.zip
|
|
unzip -q mail.zip -d /tmp/moodle/local/
|
|
rm mail.zip
|
|
#mkdir -p /tmp/moodle/local/tresipuntimportgc
|
|
#cp -R local_plugins/moodle/tresipuntimportgc/* /tmp/moodle/local/tresipuntimportgc/
|
|
|
|
cp -R /tmp/moodle/* "$SRC_FOLDER/moodle/"
|
|
rm -rf /tmp/moodle
|
|
docker exec -i dd-apps-moodle php7 admin/cli/purge_caches.php
|
|
}
|
|
|
|
upgrade_plugins_nextcloud(){
|
|
cp -R dd-apps/docker/nextcloud/src/* "$SRC_FOLDER/nextcloud/"
|
|
nextcloud_upgrade
|
|
}
|
|
|
|
upgrade_plugins_wp(){
|
|
cp -R dd-apps/docker/wordpress/src/* "$SRC_FOLDER/wordpress/"
|
|
|
|
if [ ! -d "$SRC_FOLDER/wordpress/wp-content/mu-plugins" ]; then
|
|
git clone https://gitlab.com/muplugins-multiste1/muplugins-google-sites.git "$SRC_FOLDER/wordpress/wp-content/mu-plugins"
|
|
fi
|
|
if [ ! -d "$SRC_FOLDER/wordpress/wp-content/mu-plugins/.git" ]; then
|
|
echo "WARNING: $SRC_FOLDER/wordpress/wp-content/mu-plugins is not a git repository."
|
|
echo " This could be due to old installation. To bring all new mu-plugins code for WP"
|
|
echo " remove that folder and it will be cloned and mantained with git from now on."
|
|
else
|
|
sh -c "cd $SRC_FOLDER/wordpress/wp-content/mu-plugins; git pull"
|
|
fi
|
|
chown -R 33:33 "${SRC_FOLDER}/wordpress/wp-content/mu-plugins"
|
|
# TODO: Fix this, check https://gitlab.com/DD-workspace/DD/-/issues/16
|
|
##install plugin gsite
|
|
docker exec -i dd-apps-wordpress sh -s <<-EOF
|
|
apt-get update
|
|
apt-get install -y git
|
|
apt install -y zlib1g-dev libjpeg-dev libpng-dev
|
|
apt-get install -y python3 python3-click python3-scrapy python3-unidecode python3-pillow python3-slugify
|
|
apt-get install -y curl
|
|
git clone https://gitlab.com/isard/gsite2wordpress
|
|
mv /var/www/html/gsite2wordpress /var/www
|
|
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
|
chmod +x wp-cli.phar
|
|
mv wp-cli.phar /usr/local/bin/wp
|
|
EOF
|
|
}
|
|
|
|
update_logos_and_menu(){
|
|
# docker exec -i dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)'"
|
|
# docker exec -i dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)'"
|
|
# docker exec -i dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge,value=-1)'"
|
|
# docker exec -i dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='reload'"
|
|
docker exec -i --user root dd-sso-keycloak sh -c 'rm -rf /opt/jboss/keycloak/standalone/tmp/kc-gzip-cache/*'
|
|
docker-compose build dd-sso-api && docker-compose up -d dd-sso-api
|
|
configure_nextcloud_logo
|
|
}
|
|
|
|
configure_nextcloud_logo(){
|
|
local instance_id
|
|
instance_id=$(docker exec -u www-data dd-apps-nextcloud-app php occ config:system:get instanceid)
|
|
local cachebuster
|
|
cachebuster=$(docker exec -u www-data dd-apps-nextcloud-app php occ config:app:get theming cachebuster)
|
|
docker exec -u www-data dd-apps-nextcloud-app mkdir -p "/var/www/html/data/appdata_$instance_id/theming/images"
|
|
nc_logo="${DATA_FOLDER}/nextcloud/appdata_$instance_id/theming/images/logo"
|
|
nc_background="${DATA_FOLDER}/nextcloud/appdata_$instance_id/theming/images/background"
|
|
cp custom/img/logo.png "${nc_logo}"
|
|
cp custom/img/background.png "${nc_background}"
|
|
chown 82:82 "${nc_logo}" "${nc_background}"
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming logoMime --value="image/png"
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming backgroundMime --value="image/png"
|
|
docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming cachebuster --value="$((cachebuster + 1 ))"
|
|
}
|
|
|
|
genpwd() {
|
|
if [ ! -f /usr/share/dict/words ]; then
|
|
prerequisites_pwd > /dev/null
|
|
fi
|
|
shuf -n3 /usr/share/dict/words | tr -d "\n" | tr -d "'"
|
|
}
|
|
|
|
securize() {
|
|
for dd_var in \
|
|
ADMINAPP_PASSWORD \
|
|
DDADMIN_PASSWORD \
|
|
KEYCLOAK_PASSWORD \
|
|
KEYCLOAK_DB_PASSWORD \
|
|
POSTGRES_PASSWORD \
|
|
MARIADB_PASSWORD \
|
|
MOODLE_POSTGRES_PASSWORD \
|
|
MOODLE_ADMIN_PASSWORD \
|
|
NEXTCLOUD_POSTGRES_PASSWORD \
|
|
NEXTCLOUD_ADMIN_PASSWORD \
|
|
ETHERPAD_POSTGRES_PASSWORD \
|
|
ETHERPAD_ADMIN_PASSWORD \
|
|
WORDPRESS_MARIADB_PASSWORD \
|
|
WORDPRESS_ADMIN_PASSWORD \
|
|
IPA_ADMIN_PWD; do
|
|
setconf "${dd_var}" "$(genpwd)"
|
|
done
|
|
}
|
|
|
|
setconf() {
|
|
dd_var="$(echo "$1" | tr "[:lower:]" "[:upper:]")"
|
|
dd_val="$2"
|
|
dd_line="$(printf '%s="%s"' "${dd_var:?}" "${dd_val}")"
|
|
conf_file="${3:-dd.conf}"
|
|
if grep -qE "^${dd_var:?}=" "${conf_file}"; then
|
|
# Found uncommented, replace in-place
|
|
sed -i'' -E "s!^${dd_var:?}=.*\$!${dd_line}!" "${conf_file}"
|
|
elif grep -qE "^#[[:space:]]*${dd_var:?}=" "${conf_file}"; then
|
|
# Found commented, replace in-place
|
|
sed -i'' -E "s!^#[[:space:]]*${dd_var:?}=.*\$!${dd_line}!" "${conf_file}"
|
|
else
|
|
# Not found, append
|
|
echo "${dd_line}" >> "${conf_file}"
|
|
fi
|
|
}
|
|
|
|
special_image_tags() {
|
|
# Special image tags that apply to this build
|
|
head="$(git rev-parse HEAD)"
|
|
# loop through BRANCH:TAG1[:TAG2:...:TAG_N] items
|
|
for tag_info in develop:latest main:stable; do
|
|
branch="$(echo "${tag_info}" | cut -d ':' -f 1)"
|
|
upstream="$(git rev-parse "${DD_REMOTE:-origin}/${branch}" 2>/dev/null || true)"
|
|
if [ "${head}" = "${upstream}" ]; then
|
|
# If head and upstream match, use these tags
|
|
special_tags="$(echo "${tag_info}" | cut -d ':' -f 2- | tr ':' ' ')"
|
|
echo "${special_tags}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
push_images() {
|
|
#
|
|
# Note this requires docker login on the registry
|
|
# (Runs on CI)
|
|
#
|
|
# Get images that are using the registry
|
|
images="$(docker ps --format '{{ .Names }}\t{{ .Image }}' | grep "${DD_REGISTRY:-registry.dd-work.space}")"
|
|
for extra_tag in $(special_image_tags); do
|
|
# And apply the special tags on them
|
|
for image in $(echo "${images}" | cut -f 2); do
|
|
docker tag "${image}" "${image%:*}:${extra_tag}"
|
|
done
|
|
done
|
|
image_names="$(echo "${images}" | cut -f 1 | tr '\n' '\t')"
|
|
# Finally, actually push all tags to the registry
|
|
# shellcheck disable=SC2086 # We do want multiple arguments
|
|
docker-compose push ${image_names:?}
|
|
}
|
|
|
|
# Argument handling
|
|
case "$OPERATION" in
|
|
build)
|
|
build
|
|
;;
|
|
build-devel)
|
|
build_compose_develop
|
|
;;
|
|
adminer)
|
|
extras_adminer
|
|
;;
|
|
all)
|
|
build
|
|
up
|
|
|
|
wait_for_moodle
|
|
upgrade_plugins_moodle
|
|
upgrade_plugins_nextcloud
|
|
upgrade_plugins_wp
|
|
|
|
setup_nextcloud
|
|
setup_moodle
|
|
setup_wordpress
|
|
|
|
saml --no-up
|
|
|
|
cat <<-EOF
|
|
|
|
#### After install ####
|
|
- SSO in moodle should be active. You can go to: https://moodle.$DOMAIN
|
|
If it fails, regenerate and lock certificate in moodle SAML2 connector as a local admin.
|
|
After that run ./dd-ctl saml
|
|
- SSO in nextcloud should be active. You can go to: https://nextcloud.$DOMAIN
|
|
- SSO in wordpress should be active. You should go to https://wp.$DOMAIN/wp-admin//plugins.php
|
|
|
|
#### Update customizations ####
|
|
- ./dd-ctl customize
|
|
EOF
|
|
;;
|
|
branding)
|
|
up
|
|
wait_for_moodle
|
|
update_logos_and_menu
|
|
;;
|
|
customize)
|
|
up
|
|
wait_for_moodle
|
|
setup_nextcloud
|
|
setup_wordpress
|
|
setup_moodle
|
|
;;
|
|
down)
|
|
down
|
|
;;
|
|
nextcloud-scan)
|
|
nextcloud_scan
|
|
;;
|
|
pgtuner)
|
|
extras_pgtuner
|
|
;;
|
|
prerequisites)
|
|
prerequisites_docker
|
|
prerequisites_pwd
|
|
;;
|
|
update)
|
|
ddupdate --full
|
|
;;
|
|
repo-update)
|
|
ddupdate
|
|
;;
|
|
reset-data|reset-1714)
|
|
cat <<-EOF
|
|
# Following commands RESET ALL DATA except for certificates
|
|
# execute them only if you know what you are doing
|
|
# This *will* result in DATA LOSS
|
|
"$0" down
|
|
rm -rf /opt/DD/data/*
|
|
rm -rf /opt/DD/db/*
|
|
rm -rf '$SRC_FOLDER/avatars'
|
|
rm -rf '$SRC_FOLDER/moodle'
|
|
rm -rf '$SRC_FOLDER/nextcloud'
|
|
rm -rf '$SRC_FOLDER/wordpress'
|
|
EOF
|
|
;;
|
|
restart-api)
|
|
up
|
|
wait_for_moodle
|
|
docker restart dd-sso-api
|
|
;;
|
|
saml)
|
|
saml "$@"
|
|
;;
|
|
securize)
|
|
securize
|
|
;;
|
|
setconf)
|
|
setconf "$@"
|
|
;;
|
|
up)
|
|
up
|
|
;;
|
|
upgrade-plugins)
|
|
up
|
|
wait_for_moodle
|
|
upgrade_plugins_moodle
|
|
upgrade_plugins_nextcloud
|
|
upgrade_plugins_wp
|
|
;;
|
|
yml)
|
|
cp dd.conf .env
|
|
CUSTOM_PATH=$(pwd)
|
|
. ./.env
|
|
build_compose
|
|
;;
|
|
listpatches)
|
|
listpatches
|
|
;;
|
|
push-images)
|
|
push_images
|
|
;;
|
|
failing-containers)
|
|
fc="$(docker ps --format '{{.Names}}' -f 'health=unhealthy')"
|
|
if [ -n "${fc}" ]; then
|
|
cat >&2 <<-EOF
|
|
Failing containers:
|
|
${fc}
|
|
EOF
|
|
exit 1
|
|
fi
|
|
;;
|
|
genpatches)
|
|
genpatches
|
|
;;
|
|
*)
|
|
printf "Unknown command '%s'\n\n" "$OPERATION" >&2
|
|
help >&2
|
|
exit 1
|
|
;;
|
|
esac
|