new: [opensem] add charm

This commit is contained in:
Valentin Lab
2025-09-25 16:31:23 +02:00
commit 32b0ed5645
11 changed files with 642 additions and 0 deletions

221
opensem/lib/common Normal file
View 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 + _ . - / @ :) doesnt 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])[] | .[]' )
}