new: [opensem] add charm
This commit is contained in:
10
opensem/README.org
Normal file
10
opensem/README.org
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# -*- ispell-local-dictionary: "english" -*-
|
||||||
|
#+PROPERTY: TASK_CATEG opensem
|
||||||
|
|
||||||
|
* Build source code
|
||||||
|
|
||||||
|
Using a ~Dockerfile~ and forcing latest known working ~composer.lock~
|
||||||
|
and ~yarn.lock~ to ensure reproducible build.
|
||||||
|
|
||||||
|
We provide the resulting production ready application files in a
|
||||||
|
~tar.xz~.
|
||||||
21
opensem/hooks/init
Executable file
21
opensem/hooks/init
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## Init is run on host
|
||||||
|
## For now it is run every time the script is launched, but
|
||||||
|
## it should be launched only once after build.
|
||||||
|
|
||||||
|
## Accessible variables are:
|
||||||
|
## - SERVICE_NAME Name of current service
|
||||||
|
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
|
||||||
|
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
|
||||||
|
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
|
||||||
|
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
|
||||||
|
opensem:init || exit 1
|
||||||
|
|
||||||
|
opensem:config || exit 1
|
||||||
86
opensem/hooks/log_rotate-relation-joined
Executable file
86
opensem/hooks/log_rotate-relation-joined
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## Should be executable N time in a row with same result.
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
LOGS=/var/log/opensem
|
||||||
|
|
||||||
|
php_fpm_service=$(service:traverse "$SERVICE_NAME":php-fpm) || {
|
||||||
|
err "Could not find php-fpm service for $SERVICE_NAME"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
uid_gid=$(get_service_base_image_dir_uid_gid "$php_fpm_service" /var/www/html) || {
|
||||||
|
err "Could not determine uid:gid for $php_fpm_service of dir /var/www/html"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
gid="${uid_gid#* }"
|
||||||
|
|
||||||
|
dirs=(
|
||||||
|
"$LOGS"
|
||||||
|
)
|
||||||
|
|
||||||
|
to_create=()
|
||||||
|
volumes=""
|
||||||
|
for d in "${dirs[@]}"; do
|
||||||
|
fdir="${SERVICE_DATASTORE}$d"
|
||||||
|
if [ -d "$fdir" ]; then
|
||||||
|
find "$fdir" \! -gid "$gid" -print0 | while read-0 f; do
|
||||||
|
chgrp -v "$gid" "$f" || return 1
|
||||||
|
done
|
||||||
|
find "$fdir" \! -perm -g+rwx -print0 | while read-0 f; do
|
||||||
|
chmod -v g+rwx "$f" || return 1
|
||||||
|
done
|
||||||
|
else
|
||||||
|
to_create+=("$fdir")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${#to_create[@]}" -gt 0 ]; then
|
||||||
|
mkdir -p "${to_create[@]}" || return 1
|
||||||
|
chgrp -v "${gid}" "${to_create[@]}" || return 1
|
||||||
|
chmod g+rwx "${to_create[@]}" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
rotated_count=$(relation-get rotated-count 2>/dev/null) || true
|
||||||
|
rotated_count=${rotated_count:-52}
|
||||||
|
|
||||||
|
## XXXvlab: a lot of this intelligence should be moved away into ``logrotate`` charm
|
||||||
|
DST="$CONFIGSTORE/$TARGET_SERVICE_NAME/etc/logrotate.d/$SERVICE_NAME"
|
||||||
|
file_put "$DST" <<EOF
|
||||||
|
/var/log/docker/$SERVICE_NAME/laravel.log {
|
||||||
|
weekly
|
||||||
|
missingok
|
||||||
|
dateext
|
||||||
|
dateyesterday
|
||||||
|
dateformat _%Y-%m-%d
|
||||||
|
extension .log
|
||||||
|
rotate $rotated_count
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
notifempty
|
||||||
|
create 640 root root
|
||||||
|
sharedscripts
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
opensem:config-set "LOG_CHANNEL" "single" || {
|
||||||
|
err "Could not set LOG_CHANNEL=single in opensem config"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
config-add "\
|
||||||
|
services:
|
||||||
|
$MASTER_TARGET_SERVICE_NAME:
|
||||||
|
volumes:
|
||||||
|
- $DST:/etc/logrotate.d/docker-${SERVICE_NAME}:ro
|
||||||
|
- $SERVICE_DATASTORE$LOGS:/var/log/docker/$SERVICE_NAME:rw
|
||||||
|
$php_fpm_service:
|
||||||
|
volumes:
|
||||||
|
- $SERVICE_DATASTORE$LOGS:/opt/apps/$SERVICE_NAME/storage/logs:rw
|
||||||
|
"
|
||||||
17
opensem/hooks/meilisearch_engine-relation-joined
Executable file
17
opensem/hooks/meilisearch_engine-relation-joined
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
master_key=$(service:password:get "${TARGET_SERVICE_NAME}" "master_key" internal) || exit 1
|
||||||
|
|
||||||
|
cat <<EOF >> "${OPENSEM_CONFIG_FILE}"
|
||||||
|
|
||||||
|
|
||||||
|
## meilisearch settings
|
||||||
|
|
||||||
|
SCOUT_DRIVER=meilisearch
|
||||||
|
MEILISEARCH_HOST=http://${TARGET_SERVICE_NAME}:7700
|
||||||
|
MEILISEARCH_KEY=${master_key}
|
||||||
|
EOF
|
||||||
28
opensem/hooks/mysql_database-relation-joined
Executable file
28
opensem/hooks/mysql_database-relation-joined
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
PASSWORD="$(relation-get password)"
|
||||||
|
USER="$(relation-get user)"
|
||||||
|
DBNAME="$(relation-get dbname)"
|
||||||
|
|
||||||
|
# control=$(H "$USER" "$DBNAME" "$PASSWORD")
|
||||||
|
|
||||||
|
# [ "$control" == "$(relation-get control || true)" ] && exit 0
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat <<EOF >> "${OPENSEM_CONFIG_FILE}"
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=${TARGET_SERVICE_NAME}
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=$DBNAME
|
||||||
|
DB_USERNAME=$USER
|
||||||
|
DB_PASSWORD=$PASSWORD
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# relation-set control "$control"
|
||||||
|
|
||||||
|
info "Configured opensem code for mysql access."
|
||||||
7
opensem/hooks/pre_deploy
Executable file
7
opensem/hooks/pre_deploy
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mv -v "${OPENSEM_CONFIG_FILE}" "${OPENSEM_CONFIG_FILE%.prepare}"
|
||||||
88
opensem/hooks/publish_dir-relation-joined
Executable file
88
opensem/hooks/publish_dir-relation-joined
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
domain=$(relation-get domain) || exit 1
|
||||||
|
url=$(relation-get url) || exit 1
|
||||||
|
|
||||||
|
location=$CONFIGSTORE/$BASE_SERVICE_NAME/var/www/$domain
|
||||||
|
|
||||||
|
php_fpm_service=$(service:traverse "$SERVICE_NAME":php-fpm) || {
|
||||||
|
err "Could not find php-fpm service for $SERVICE_NAME"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
uid_gid=$(get_service_base_image_dir_uid_gid "$php_fpm_service" /var/www/html) || {
|
||||||
|
err "Could not determine uid:gid for $php_fpm_service of dir /var/www/html"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
gid="${uid_gid#* }"
|
||||||
|
|
||||||
|
dirs=(
|
||||||
|
/var/cache/opensem/bootstrap
|
||||||
|
/var/cache/opensem/framework
|
||||||
|
/var/lib/opensem/views
|
||||||
|
/var/lib/opensem/sessions
|
||||||
|
/var/lib/opensem/app
|
||||||
|
/var/lib/opensem/app/public
|
||||||
|
/var/log/opensem
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
to_create=()
|
||||||
|
volumes=""
|
||||||
|
for d in "${dirs[@]}"; do
|
||||||
|
fdir="${SERVICE_DATASTORE}$d"
|
||||||
|
if [ -d "$fdir" ]; then
|
||||||
|
find "$fdir" \! -gid "$gid" -print0 | while read-0 f; do
|
||||||
|
chgrp -v "$gid" "$f" || return 1
|
||||||
|
done
|
||||||
|
find "$fdir" \! -perm -g+rwx -print0 | while read-0 f; do
|
||||||
|
chmod -v g+rwx "$f" || return 1
|
||||||
|
done
|
||||||
|
else
|
||||||
|
to_create+=("$fdir")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${#to_create[@]}" -gt 0 ]; then
|
||||||
|
mkdir -p "${to_create[@]}" || return 1
|
||||||
|
chgrp -v "${gid}" "${to_create[@]}" || return 1
|
||||||
|
chmod g+rwx "${to_create[@]}" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
opensem:config-set APP_URL "$url"
|
||||||
|
|
||||||
|
dev=$(options-get dev 2>/dev/null) || true
|
||||||
|
if [ -n "$dev" ]; then
|
||||||
|
# if ! [ -d "$dev" ]; then
|
||||||
|
# err "The 'dev' option is set to '$dev' but this is not a directory."
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
|
||||||
|
OPENSEM_CODE="$dev"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
service:docker-compose:directive-merge "$MASTER_TARGET_SERVICE_NAME" <<EOF
|
||||||
|
volumes:
|
||||||
|
- $SERVICE_DATASTORE/var/lib/opensem/app/public:/var/www/$domain/storage:ro
|
||||||
|
EOF
|
||||||
|
|
||||||
|
config-add "
|
||||||
|
services:
|
||||||
|
$php_fpm_service:
|
||||||
|
volumes:
|
||||||
|
# - $OPENSEM_CODE/public:/var/www/$domain:ro
|
||||||
|
- $OPENSEM_CODE:/opt/apps/$SERVICE_NAME:ro
|
||||||
|
- $SERVICE_DATASTORE/var/cache/opensem/bootstrap:/opt/apps/$SERVICE_NAME/bootstrap/cache:rw
|
||||||
|
- $SERVICE_DATASTORE/var/cache/opensem/framework:/opt/apps/$SERVICE_NAME/storage/framework/cache:rw
|
||||||
|
- $SERVICE_DATASTORE/var/lib/opensem/views:/opt/apps/$SERVICE_NAME/storage/framework/views:rw
|
||||||
|
- $SERVICE_DATASTORE/var/lib/opensem/sessions:/opt/apps/$SERVICE_NAME/storage/framework/sessions:rw
|
||||||
|
## Required to give PHP write access to this dir
|
||||||
|
- $SERVICE_DATASTORE/var/lib/opensem/app:/opt/apps/$SERVICE_NAME/storage/app:rw
|
||||||
|
- $SERVICE_DATASTORE/var/lib/opensem/app/public:/opt/apps/$SERVICE_NAME/storage/app/public:rw
|
||||||
|
|
||||||
|
"
|
||||||
21
opensem/hooks/redis_database-relation-joined
Executable file
21
opensem/hooks/redis_database-relation-joined
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
password=$(relation-get password) || {
|
||||||
|
err "Can't get password for '$SERVICE_NAME' from '$TARGET_SERVICE_NAME'."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cat <<EOF >> "${OPENSEM_CONFIG_FILE}"
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=redis
|
||||||
|
REDIS_HOST=${TARGET_SERVICE_NAME}
|
||||||
|
REDIS_PASSWORD=$password
|
||||||
|
REDIS_PORT=6379
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
info "Configured $SERVICE_NAME code for $TARGET_SERVICE_NAME access."
|
||||||
66
opensem/hooks/smtp_server-relation-joined
Executable file
66
opensem/hooks/smtp_server-relation-joined
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. lib/common
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
host=$(relation-get host)
|
||||||
|
port=$(relation-get port)
|
||||||
|
connection_security=$(relation-get connection-security)
|
||||||
|
auth_method=$(relation-get auth-method)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
declare -A ENV
|
||||||
|
|
||||||
|
ENV[DRIVER]=smtp
|
||||||
|
ENV[HOST]="$host"
|
||||||
|
ENV[PORT]="$port"
|
||||||
|
|
||||||
|
case "$connection_security" in
|
||||||
|
"none")
|
||||||
|
ENV[ENCRYPTION]=null
|
||||||
|
;;
|
||||||
|
"ssl/tls")
|
||||||
|
ENV[ENCRYPTION]="tls"
|
||||||
|
;;
|
||||||
|
"ssl")
|
||||||
|
ENV[ENCRYPTION]="ssl"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unsupported connection security: $connection_security"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$auth_method" in
|
||||||
|
"none")
|
||||||
|
ENV[USERNAME]=null
|
||||||
|
;;
|
||||||
|
"password")
|
||||||
|
login=$(relation-get login) || true
|
||||||
|
ENV[USERNAME]="$login"
|
||||||
|
|
||||||
|
password=$(relation-get password) || true
|
||||||
|
ENV[PASSWORD]="$password"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unsupported auth method: $auth_method"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
mail_from=$(relation-get mail-from) || true
|
||||||
|
if [ -n "$mail_from" ]; then
|
||||||
|
ENV[FROM_ADDRESS]="$mail_from"
|
||||||
|
fi
|
||||||
|
|
||||||
|
from_name=$(relation-get from-name) || true
|
||||||
|
if [ -n "$from_name" ]; then
|
||||||
|
ENV[FROM_NAME]="$from_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for key in "${!ENV[@]}"; do
|
||||||
|
value=${ENV[$key]}
|
||||||
|
opensem:config-set "MAIL_$key" "$value"
|
||||||
|
done
|
||||||
221
opensem/lib/common
Normal file
221
opensem/lib/common
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
# -*- mode: shell-script -*-
|
||||||
|
|
||||||
|
OPENSEM_DIR="/opt/apps/opensem"
|
||||||
|
OPENSEM_CODE="$SERVICE_CONFIGSTORE$OPENSEM_DIR"
|
||||||
|
OPENSEM_RELEASE=1.0.0-rc.1
|
||||||
|
OPENSEM_URL=https://docker.0k.io/downloads/opensem-"${OPENSEM_RELEASE}".tar.xz
|
||||||
|
OPENSEM_CONFIG_FILE="${OPENSEM_CODE}"/.env.prepare
|
||||||
|
|
||||||
|
opensem:init() {
|
||||||
|
current_version=""
|
||||||
|
if [ -e "${OPENSEM_CODE}/.version" ]; then
|
||||||
|
current_version="$(cat "${OPENSEM_CODE}/.version")" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Note: previous content will be removed, if not in `.git` and no
|
||||||
|
## version matching current one
|
||||||
|
if ! [ -d "${OPENSEM_CODE}/.git" ]; then
|
||||||
|
mkdir -p "${OPENSEM_CODE}" &&
|
||||||
|
cd "${OPENSEM_CODE}" &&
|
||||||
|
git init . &&
|
||||||
|
git config user.email "root@localhost" &&
|
||||||
|
git config user.name "Root" || {
|
||||||
|
err "Couldn't create directory ${OPENSEM_CODE}, or init it with git."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Check if we need to upgrade code.
|
||||||
|
if [ "$current_version" == "$OPENSEM_RELEASE" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "${OPENSEM_CODE}" || return 1
|
||||||
|
if [ -d "$PWD"/.git ]; then
|
||||||
|
rm -rf "${PWD:?}"/* "$PWD"/{.version,.env} || return 1
|
||||||
|
else
|
||||||
|
err "Can't find the '.git' directory in ${OPENSEM_CODE}."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
curl -L "$OPENSEM_URL" | tar xJ || {
|
||||||
|
err "Couldn't download $OPENSEM_URL."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
sed -ri "s% __DIR__.'/../% '/opt/apps/$SERVICE_NAME/%g" public/index.php || {
|
||||||
|
err "Couldn't patch public/index.php."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
echo "$OPENSEM_RELEASE" > .version
|
||||||
|
git add -A . || {
|
||||||
|
err "'git add -A .' in '${OPENSEM_CODE}' failed."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if git diff --staged -s --exit-code; then
|
||||||
|
info "No differences with last saved version."
|
||||||
|
else
|
||||||
|
git commit -m "Release $OPENSEM_RELEASE" || {
|
||||||
|
err "'git commit' failed."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
rm -rf "$SERVICE_DATASTORE/var/cache/opensem/"*
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
opensem:config() {
|
||||||
|
|
||||||
|
APP_ENV=$(options-get app-env 2>/dev/null) || true
|
||||||
|
APP_ENV=${APP_ENV:-production}
|
||||||
|
|
||||||
|
cat <<EOF > "${OPENSEM_CONFIG_FILE}"
|
||||||
|
APP_NAME=OpenSEM
|
||||||
|
APP_ENV=${APP_ENV}
|
||||||
|
APP_KEY=base64:$(password:get app_key internal 32 base64)
|
||||||
|
APP_DEBUG=false
|
||||||
|
|
||||||
|
LOG_CHANNEL=stderr
|
||||||
|
|
||||||
|
CACHE_DRIVER=array
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=180
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
|
||||||
|
CLOCKWORK_ENABLE=false
|
||||||
|
XRAY_ENABLED=false
|
||||||
|
DEBUGBAR_ENABLED=false
|
||||||
|
QUERY_DETECTOR_ENABLED=false
|
||||||
|
MICROSCOPE_ENABLED=false
|
||||||
|
|
||||||
|
WKHTML_PDF_BINARY='"wkhtmltopdf"'
|
||||||
|
WKHTML_IMG_BINARY='"wkhtmltoimage"'
|
||||||
|
|
||||||
|
LIMIT_UUID_LENGTH_32=true
|
||||||
|
AUTHENTICATION_LOG_NOTIFY=false
|
||||||
|
|
||||||
|
REPORTING_API_ENABLED=false
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1
|
||||||
|
echo "Service def: '$service_def'" >&2
|
||||||
|
env=$(e "$service_def" | shyaml get-value -y options.env 2>/dev/null) || true
|
||||||
|
echo "Env: '$env'" >&2
|
||||||
|
if [ -n "$env" ]; then
|
||||||
|
e "$env" | opensem:config-merge || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
artisan() {
|
||||||
|
|
||||||
|
export COMPOSE_IGNORE_ORPHANS=true
|
||||||
|
|
||||||
|
php_fpm_service=$(service:traverse "$SERVICE_NAME":php-fpm) || return 1
|
||||||
|
## We don't want post deploy that is doing the final http initialization.
|
||||||
|
compose --debug -q --no-init --no-post-deploy --no-pre-deploy \
|
||||||
|
--without-relation="$SERVICE_NAME":publish-dir \
|
||||||
|
run \
|
||||||
|
"${artisan_docker_run_opts[@]}" \
|
||||||
|
-T --rm -w /opt/apps/"$SERVICE_NAME" \
|
||||||
|
--entrypoint php \
|
||||||
|
-u www-data "$php_fpm_service" artisan "$@" | cat
|
||||||
|
|
||||||
|
return "${PIPESTATUS[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
dotenv:quote() {
|
||||||
|
local val="$1"
|
||||||
|
|
||||||
|
# Empty string → quoted so the emptiness is explicit
|
||||||
|
if [[ -z "$val" ]]; then
|
||||||
|
printf "''"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Plain token (alnum + _ . - / @ :) doesn’t need quoting
|
||||||
|
if [[ "$val" =~ ^[A-Za-z0-9_.:/@-]+$ ]]; then
|
||||||
|
printf '%s' "$val"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If it has no single quotes or newlines, prefer single quotes
|
||||||
|
if [[ "$val" != *"'"* && "$val" != *$'\n'* && "$val" != *$'\r'* ]]; then
|
||||||
|
printf "'%s'" "$val"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallback: double quotes with escaped specials + newlines
|
||||||
|
local escaped="$val"
|
||||||
|
escaped=${escaped//\\/\\\\}
|
||||||
|
escaped=${escaped//$'\n'/\\n}
|
||||||
|
escaped=${escaped//$'\r'/\\r}
|
||||||
|
escaped=${escaped//$'\t'/\\t}
|
||||||
|
escaped=${escaped//\"/\\\"}
|
||||||
|
escaped=${escaped//\$/\\$}
|
||||||
|
escaped=${escaped//\`/\\\`}
|
||||||
|
printf "\"%s\"" "$escaped"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Set or add a single key/value to .env
|
||||||
|
opensem:config-set() {
|
||||||
|
local key="$1" val="$2"
|
||||||
|
## sanity check on key:
|
||||||
|
if ! [[ "$key" =~ ^[A-Z_]+$ ]]; then
|
||||||
|
err "Invalid key name '$key', only [A-Z_] are allowed."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
val=$(dotenv:quote "$val") || return 1
|
||||||
|
|
||||||
|
## modify or add in "$OPENSEM_CONFIG_FILE"
|
||||||
|
if grep -qE "^[[:space:]]*$key=" "${OPENSEM_CONFIG_FILE}"; then
|
||||||
|
sed -ri "s%^[[:space:]]*${key}=.*$%${key}=${val}%" "${OPENSEM_CONFIG_FILE}" || return 1
|
||||||
|
else
|
||||||
|
echo "${key}=${val}" >> "${OPENSEM_CONFIG_FILE}" || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
opensem:config-merge() {
|
||||||
|
local key val type
|
||||||
|
local sep=
|
||||||
|
local prefix=
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
prefix="$(IFS="_"; echo "$*")_"
|
||||||
|
fi
|
||||||
|
while read-0 key type val; do
|
||||||
|
## sanity check on key:
|
||||||
|
if ! [[ "$key" =~ ^[a-z-]+$ ]]; then
|
||||||
|
err "Invalid key name '$key', only [a-z-] are allowed."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
case "${type##*\!}" in
|
||||||
|
map|seq)
|
||||||
|
e "$val" | opensem:config-merge "$@" "$key" || return 1
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
bool)
|
||||||
|
val="${val%$'\n'}"
|
||||||
|
case "${val,,}" in
|
||||||
|
true|ok|yes|y)
|
||||||
|
val=true
|
||||||
|
;;
|
||||||
|
false|ko|nok|no|n)
|
||||||
|
val=false
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "Invalid value for ${WHITE}$key$NORMAL, please use a boolean value."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
str|*)
|
||||||
|
val="${val%$'\n'}"
|
||||||
|
val="$(dotenv:quote "$val")"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
key=${key//-/_}
|
||||||
|
key=${key^^}
|
||||||
|
key=${prefix^^}$key
|
||||||
|
opensem:config-set "$key" "$val" || return 1
|
||||||
|
done < <( yq -0 'to_entries | map([.key, .value | type, .value | to_yaml])[] | .[]' )
|
||||||
|
}
|
||||||
77
opensem/metadata.yml
Normal file
77
opensem/metadata.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
description: OpenSem
|
||||||
|
subordinate: true
|
||||||
|
requires:
|
||||||
|
web-publishing-directory:
|
||||||
|
interface: publish-dir
|
||||||
|
scope: container
|
||||||
|
|
||||||
|
|
||||||
|
uses:
|
||||||
|
mysql-database:
|
||||||
|
#constraint: required | recommended | optional
|
||||||
|
#auto: pair | summon | none ## default: pair
|
||||||
|
constraint: required
|
||||||
|
auto: summon
|
||||||
|
solves:
|
||||||
|
database: "main storage"
|
||||||
|
publish-dir:
|
||||||
|
#constraint: required | recommended | optional
|
||||||
|
#auto: pair | summon | none ## default: pair
|
||||||
|
scope: container
|
||||||
|
constraint: required
|
||||||
|
auto: summon
|
||||||
|
solves:
|
||||||
|
container: "main running server"
|
||||||
|
default-options:
|
||||||
|
location: !var-expand "$CONFIGSTORE/$BASE_SERVICE_NAME/opt/apps/opensem/public"
|
||||||
|
backup:
|
||||||
|
constraint: recommended
|
||||||
|
auto: pair
|
||||||
|
solves:
|
||||||
|
backup: "Automatic regular backup"
|
||||||
|
default-options:
|
||||||
|
## First pattern matching wins, no pattern matching includes.
|
||||||
|
## include-patterns are checked first, then exclude-patterns
|
||||||
|
## Patterns rules:
|
||||||
|
## - ending / for directory
|
||||||
|
## - '*' authorized
|
||||||
|
## - must start with a '/', will start from $SERVICE_DATASTORE
|
||||||
|
# include-patterns:
|
||||||
|
# - /var/backups/pg/
|
||||||
|
exclude-patterns:
|
||||||
|
- "/var/cache/" ## cache
|
||||||
|
- "/var/lib/opensem/sessions/" ## sessions
|
||||||
|
- "/var/lib/opensem/views/" ## compiled blade cache
|
||||||
|
|
||||||
|
php-fpm:
|
||||||
|
#constraint: required | recommended | optional
|
||||||
|
#auto: pair | summon | none ## default: pair
|
||||||
|
constraint: required
|
||||||
|
auto: summon
|
||||||
|
solves:
|
||||||
|
container: "main php interpreter"
|
||||||
|
default-options:
|
||||||
|
extensions:
|
||||||
|
- pdo_mysql gd intl
|
||||||
|
sys-tools:
|
||||||
|
- fonts wkhtmltopdf
|
||||||
|
meilisearch-engine:
|
||||||
|
#constraint: required | recommended | optional
|
||||||
|
#auto: pair | summon | none ## default: pair
|
||||||
|
constraint: required
|
||||||
|
auto: summon
|
||||||
|
solves:
|
||||||
|
container: "meilisearch engine"
|
||||||
|
smtp-server:
|
||||||
|
constraint: required
|
||||||
|
auto: pair
|
||||||
|
solves:
|
||||||
|
mail: "verify email"
|
||||||
|
log-rotate:
|
||||||
|
#constraint: required | recommended | optional
|
||||||
|
#auto: pair | summon | none ## default: pair
|
||||||
|
constraint: recommended
|
||||||
|
auto: pair
|
||||||
|
solves:
|
||||||
|
unmanaged-logs: "in docker logs"
|
||||||
|
#default-options:
|
||||||
Reference in New Issue
Block a user