new: [outline] add new charm

This commit is contained in:
default
2024-05-21 11:04:48 +02:00
committed by default
parent ea46224bdc
commit 02755e516c
7 changed files with 350 additions and 0 deletions

117
outline/README.org Normal file
View File

@@ -0,0 +1,117 @@
# -*- ispell-local-dictionary: "english" -*-
* Info
From: https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t
* Usage
Config info: https://github.com/outline/outline/blob/main/.env.sample
Odoo config: if you configure odoo OIDC connector, the callback url
should be like this : https://<YOUR_OUTLINE>:443/auth/oidc.callback
#Requires a =smtp-server= provider to be functional, you can use
#=smtp-stub= charm to provide information to externally managed =SMTP=.
#+begin_src yaml
outline:
options:
sender-email: #the sender email (beware the conf of your SMTP server)
oidc-client-id: #the client id of your OIDC provider
oidc-client-secret: #the client
oidc-auth-uri: #the host of your OIDC provider
oidc-token-uri: #the token uri of your OIDC provider
oidc-user-info-uri: #the user info uri of your OIDC provider
oidc-logout-uri: #the login uri of your OIDC provider
#smtp-stub:
# options:
# host: smtp.myhost.com
# port: 465
# connection-security: "ssl/tls"
# auth-method: password #IMPORTANT: if not present login password doesnt work
# login: myuser
# password: myp4ssw0rd
##+end_src
** Odoo 14
We monkey-patch odoo in order to make it work, be sure to use latest version in 14.0 of galicea openIDConnection module
* Building a new image
We use the official image with an added patch due to 2 bugs:
- https://github.com/outline/outline/issues/6859
- second was not reported yet
Note that a PR was pushed with a fix on the first bug. But this was not yet tested.
These fix are on 0.76.0
** First fix
We need to add "url.port = '';" in ~build/server/middlewares/passport.js~ to remove the port. Note that this is a bad fix but works for our setup.
#+begin_src bash
IMAGE=docker.0k.io/outline:0.76.0-elabore
echo 'apk add patch bash' | dupd -u "$IMAGE" -- -u 1
cat <<'EOF1' | dupd -u "$IMAGE" -- -u 0
patch -p 1 <<'EOF2'
--- a/build/server/middlewares/passport.js
+++ b/build/server/middlewares/passport.js
@@ -40,6 +40,7 @@
const requestHost = ctx.get("host");
const url = new URL("".concat(reqProtocol, "://").concat(requestHost).concat(redirectUrl));
url.host = host;
+ url.port = '';
return ctx.redirect("".concat(url.toString()).concat(hasQueryString ? "&" : "?", "notice=").concat(notice));
}
if (_env.default.isDevelopment) {
EOF2
EOF1
#+end_src
** Second fix
Upon calling "/oidc" url, outline will return "Set-Cookie" header
with a "domain:" value that is incorrect (still the inner docker
domain: "outline" instead of the outer proxy domain from the frontend.)
Fortunately we can simply remove the value "domain" from the cookie by
commenting only 2 lines in ~build/server/utils/passport.js~.
The patches will change the "build/" files, so this is a very temporary and brittle fix.
#+begin_src bash
IMAGE=docker.0k.io/outline:0.76.0-elabore
cat <<'EOF1' | dupd -u "$IMAGE" -- -u 0
patch -p 1 <<'EOF2'
--- a/build/server/utils/passport.js.orig
+++ b/build/server/utils/passport.js
@@ -37,7 +37,7 @@
const state = buildState(host, token, client);
ctx.cookies.set(this.key, state, {
expires: (0, _dateFns.addMinutes)(new Date(), 10),
- domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
+ //domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
});
callback(null, token);
});
@@ -53,7 +53,7 @@
// Destroy the one-time pad token and ensure it matches
ctx.cookies.set(this.key, "", {
expires: (0, _dateFns.subMinutes)(new Date(), 1),
- domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
+ //domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
});
if (!token || token !== providedToken) {
return callback((0, _errors.OAuthStateMismatchError)(), false, token);
EOF2
EOF1
#+end_src

74
outline/hooks/init Executable file
View File

@@ -0,0 +1,74 @@
#!/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
set -e
PASSWORD_FILE="$SERVICE_DATASTORE"/.compose/password/secret-key
UTILS_SECRET="$SERVICE_DATASTORE"/.compose/password/utils-secret
if ! [ -f "$UTILS_SECRET" ]; then
info "Generating secret password"
mkdir -p "${UTILS_SECRET%/*}"
umask 077
openssl rand -hex 32 > "$UTILS_SECRET"
else
info "Using existing utils-secret"
fi
if ! [ -f "$PASSWORD_FILE" ]; then
info "Generating secret password"
mkdir -p "${PASSWORD_FILE%/*}"
umask 077
openssl rand -hex 32 > "$PASSWORD_FILE"
else
info "Using existing secret password"
fi
secret_password=$(cat "$PASSWORD_FILE")
utils_secret=$(cat "$UTILS_SECRET")
sender=$(options-get sender-email) || exit 1
oidc_client_id=$(options-get oidc-client-id) || exit 1
oidc_client_secret=$(options-get oidc-client-secret) || exit 1
oidc_auth_uri=$(options-get oidc-auth-uri) || exit 1
oidc_token_uri=$(options-get oidc-token-uri) || exit 1
oidc_user_info_uri=$(options-get oidc-user-info-uri) || exit 1
oidc_logout_uri=$(options-get oidc-logout-uri) || exit 1
init-config-add "
$SERVICE_NAME:
volumes:
- $SERVICE_DATASTORE:/var/lib/outline/data
environment:
SMTP_FROM_EMAIL: \"$sender\"
DEFAULT_LANGUAGE: \"fr_FR\"
SECRET_KEY: \"$secret_password\"
UTILS_SECRET: \"$utils_secret\"
OIDC_CLIENT_ID: \"$oidc_client_id\"
OIDC_CLIENT_SECRET: \"$oidc_client_secret\"
OIDC_AUTH_URI: \"$oidc_auth_uri\"
OIDC_TOKEN_URI: \"$oidc_token_uri\"
OIDC_USERINFO_URI: \"$oidc_user_info_uri\"
OIDC_LOGOUT_URI: \"$oidc_logout_uri\"
OIDC_SCOPES: \"openid\"
OIDC_USERNAME_CLAIM: \"preferred_username\"
OIDC_DISPLAY_NAME: \"OpenID Connect\"
NODE_ENV: \"production\"
LOG_LEVEL: \"debug\"
FORCE_HTTPS: \"false\"
FILE_STORAGE: \"local\"
#DEVELOPMENT_UNSAFE_INLINE_CSP: \"true\"
#DEBUG: \"http\"
"

View File

@@ -0,0 +1,18 @@
#!/bin/bash
set -e
PASSWORD="$(relation-get password)"
USER="$(relation-get user)"
DBNAME="$(relation-get dbname)"
config-add "\
services:
$MASTER_BASE_SERVICE_NAME:
environment:
DATABASE_URL: postgres://$USER:$PASSWORD@$TARGET_SERVICE_NAME:5432/$DBNAME
PGSSLMODE: disable
"
info "Configured $SERVICE_NAME code for $TARGET_SERVICE_NAME access."

View File

@@ -0,0 +1,25 @@
#!/bin/bash
set -e
# USER="$(relation-get user)"
# DBNAME="$(relation-get dbname)"
# PASSWORD=$(relation-get password) || {
# err "Can't get password for '$SERVICE_NAME' from '$TARGET_SERVICE_NAME'."
# exit 1
# }
PASSWORD=$(relation-get password) || {
err "Can't get password for '$SERVICE_NAME' from '$TARGET_SERVICE_NAME'."
exit 1
}
config-add "\
services:
$MASTER_BASE_SERVICE_NAME:
environment:
REDIS_URL: redis://:$PASSWORD@$TARGET_SERVICE_NAME:6379
"
info "Configured $SERVICE_NAME code for $TARGET_SERVICE_NAME access."

View File

@@ -0,0 +1,21 @@
#!/bin/bash
set -e
host=$(relation-get host) || exit 1
port=$(relation-get port) || exit 1
user=$(relation-get login) || exit 1
password="$(relation-get password)" || exit 1
config-add "\
services:
$MASTER_BASE_SERVICE_NAME:
environment:
SMTP_USERNAME: \"$user\"
SMTP_PASS: \"${password//\$/\$\$}\"
SMTP_HOST: \"$host\"
SMTP_PORT: \"$port\"
#SMTP_SECURE: \"false\"
"

View File

@@ -0,0 +1,48 @@
#!/bin/bash
set -e
URL=$(relation-get url) || {
echo "Failed to query for 'url' value"
exit 1
}
DOMAIN_PATH="${URL#*://}"
if [[ "$DOMAIN_PATH" == *"/"* ]]; then
DOMAIN="${DOMAIN_PATH%%/*}"
UPATH="/${DOMAIN_PATH#*/}"
else
DOMAIN="${DOMAIN_PATH}"
UPATH=""
fi
PROTO="${URL%:*}"
if [[ "$DOMAIN" == *":"* ]]; then
PORT="${DOMAIN#*:}"
DOMAIN="${DOMAIN%%:*}"
else
case "$PROTO" in
http)
PORT=80
;;
https)
PORT=443
;;
*)
echo "Unknown portocol '$PROTO' in url '$URL'."
exit 1
;;
esac
fi
config-add "\
services:
$MASTER_BASE_SERVICE_NAME:
environment:
URL: \"${PROTO}://${DOMAIN}:${PORT}${UPATH}\"
"

47
outline/metadata.yml Normal file
View File

@@ -0,0 +1,47 @@
docker-image: docker.0k.io/outline:0.76.0-elabore
uses:
postgres-database:
#constraint: required | recommended | optional
#auto: pair | summon | none ## default: pair
constraint: required
auto: summon
solves:
database: "main storage"
default-options:
extensions:
- uuid-ossp
redis-database:
constraint: required
auto: summon
solves:
database: "short time storage"
smtp-server:
constraint: required
auto: summon
solves:
proxy: "Public access"
web-proxy:
#constraint: required | recommended | optional
#auto: pair | summon | none ## default: pair
constraint: recommended
auto: pair
solves:
proxy: "Public access"
default-options:
target: !var-expand ${MASTER_BASE_SERVICE_NAME}:3000
apache-custom-rules:
- !var-expand |
## Use RewriteEngine to handle WebSocket connection upgrades
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*)\$ ws://${MASTER_BASE_SERVICE_NAME}:3000/\$1 [P,L]
backup:
constraint: recommended
auto: pair
solves:
backup: "Automatic regular backup"
default-options: