Commit d1bc0460 authored by Lars Kruse's avatar Lars Kruse
Browse files

feat(deb): add element-web-installer package

The element-web client will be embedded or integrated in grouprise in
order to provide instant messaging via matrix.
parent 09348fa8
......@@ -153,6 +153,19 @@ Description: Web platform that enables social action and solidarity
pre-packaged python virtual environment (venv) for running the
grouprise application.
Package: element-web-installer
Architecture: all
Depends:
curl,
debconf,
gpgv,
jq,
moreutils,
Suggests: httpd
Description: Installer for the Matrix web client Element
Download the Element web client and keep it updated.
Local configuration is applied automatically.
Package: stadtgestalten
Architecture: any
Depends: grouprise
......
Overview
--------
This package provides a script for downloading, verifying and extracting a release of the
element-web [1] client for the Matrix [2] network.
The element-web client is extracted to /var/lib/element-web-installer/.
The element-web client is updated automatically via a daily cron job.
Configuration
-------------
Local customizations can be placed below /etc/element-web/. At least config.json [3]
Every file somewhere below this directory is symlinked into the directory of the extracted
element-web client, whenever the client is updated.
Web server configuration
------------------------
The web client's directory may simply be published by your webserver.
Example configuration for apache2:
<VirtualHost *>
ServerName example.org
DocumentRoot /var/lib/element-web-installer
<Directory /var/lib/element-web-installer>
Require all granted
Options SymLinksIfOwnerMatch
</Directory>
</VirtualHost>
Example configuration for nginx:
server {
server_name example.org;
root /var/lib/element-web-installer;
}
[1] https://element.io/
[2] https://matrix.org/
[3] https://github.com/vector-im/element-web/blob/develop/docs/config.md
12 4 * * * root chronic /usr/sbin/element-web-installer upgrade
All files below the directory /etc/element-web/ can be used to add files to the
element-web directory or override existing files (via symlinks).
Probably you want to add at least your config.json file [1] and maybe additional assets to be
published via HTTP (e.g. a custom logo).
[1] https://github.com/vector-im/element-web/blob/develop/docs/config.md
<VirtualHost *>
ServerName localhost
DocumentRoot /var/lib/element-web-installer/htdocs
<Directory /var/lib/element-web-installer/htdocs>
Require all granted
</Directory>
</VirtualHost>
#!/bin/sh
#
# Download, verify and extract a release of the element-web client.
#
# License: GPLv3 or later
#
set -eu
DOWNLOAD_BASE_URL=https://github.com
DOWNLOAD_PROJECT_URL_PATH=vector-im/element-web
DOWNLOAD_APP_NAME=element
SIGNING_KEYRING_PATH=${SIGNING_KEYRING_PATH:-/usr/share/element-web-installer/trustedkeys.gpg}
INSTALL_PATH=${INSTALL_PATH:-/var/lib/element-web-installer/htdocs}
SETTINGS_PATH=${SETTINGS_PATH:-/etc/element-web}
get_latest_version() {
curl -sSL --fail "$DOWNLOAD_BASE_URL/$DOWNLOAD_PROJECT_URL_PATH/releases/latest" \
| grep "<a href=\"/$DOWNLOAD_PROJECT_URL_PATH/releases/download/v[0-9.]\+/${DOWNLOAD_APP_NAME}-v[0-9.]\+.tar.gz[^.]" \
| cut -f 2 -d '"' \
| sed "s|^.*/${DOWNLOAD_APP_NAME}-v||; s|\.tar\.gz$||"
}
get_installed_version() {
# return the currently installed version (or empty, if not installed)
cat "$INSTALL_PATH/version" 2>/dev/null || true
}
get_download_url() {
local version="$1"
echo "$DOWNLOAD_BASE_URL/$DOWNLOAD_PROJECT_URL_PATH/releases/download/v$version/${DOWNLOAD_APP_NAME}-v$version.tar.gz"
}
get_download_signature_url() {
local version="$1"
echo "$(get_download_url "$version").asc"
}
apply_local_settings() {
local destination_path="$1"
(cd "$SETTINGS_PATH" && find . -type f) | cut -d / -f 2- | while read -r fname; do
mkdir -p "$destination_path/$(dirname "$fname")"
ln -sfn "$SETTINGS_PATH/$fname" "$destination_path/$fname"
done
}
extract_archive_to_destination() {
local archive_path="$1"
local destination_path="$2"
local temp_dest
mkdir -p "$(dirname "$destination_path")"
temp_dest=$(mktemp -d --tmpdir="$(dirname "$destination_path")" element-web-installer-XXXXXX)
# restrict the scope of trap
(
trap 'rm -rf "'"$temp_dest"'"' EXIT
tar -C "$temp_dest" --strip-components=1 -xzf "$archive_path"
chmod 755 "$temp_dest"
apply_local_settings "$temp_dest"
rm -rf "$destination_path"
mv "$temp_dest" "$destination_path"
trap - EXIT
)
}
extract_verified_download() {
local target_path="$1"
local target_version="$2"
local download_dir archive_path signature_path
download_dir=$(mktemp -d)
# restrict the scope of trap
(
trap 'rm -rf "'"$download_dir"'"' EXIT
archive_path=$download_dir/archive.tar.gz
signature_path=$download_dir/signature.asc
curl -sSL --fail "$(get_download_url "$target_version")" >"$archive_path"
curl -sSL --fail "$(get_download_signature_url "$target_version")" >"$signature_path"
# suppress the verification summary in case of success (via "chronic")
if chronic gpgv --keyring="$SIGNING_KEYRING_PATH" "$signature_path" "$archive_path"; then
extract_archive_to_destination "$archive_path" "$target_path"
else
echo >&2 "Failed to verify signature. Refusing to unpack downloaded package."
false
fi
trap - EXIT
)
}
if [ $# -gt 0 ]; then
ACTION=$1
shift
else
ACTION=status
fi
case "$ACTION" in
status)
printf 'Currently installed version:\t%s\n' "$(get_installed_version)"
printf 'Latest available version:\t%s\n' "$(get_latest_version)"
;;
upgrade)
wanted_version=${1:-latest}
[ "$wanted_version" = "latest" ] && wanted_version=$(get_latest_version)
if [ "$wanted_version" = "$(get_installed_version)" ]; then
echo "Version '$wanted_version' is already installed. Nothing needs to be done."
else
echo "Dowloading and extracting element-web version '$wanted_version' ..."
extract_verified_download "$INSTALL_PATH" "$wanted_version"
fi
;;
show-installed-version)
installed_version=$(get_installed_version)
if [ -z "$installed_version" ]; then
echo >&2 "element-web was not downloaded to '$INSTALL_PATH', yet."
exit 2
else
printf '%s\n' "$installed_version"
fi
;;
show-latest-version)
get_latest_version
;;
apply-configuration)
apply_local_settings "$INSTALL_PATH"
;;
help|--help)
echo "Syntax: $(basename "$0") ACTION"
echo " upgrade [VERSION] - upgrade the element directory ($INSTALL_PATH) to the specified version (default: latest) and apply the local configuration"
echo " apply-configuration - apply the local configuration ($SETTINGS_PATH) to the element directory ($INSTALL_PATH)"
echo " show-installed-version - output the currently installed version"
echo " show-latest-version - output the latest released version of element-web"
echo
;;
*)
"$0" help >&2
exit 1
;;
esac
server {
server_name localhost;
root /var/lib/element-web-installer/htdocs;
}
#!/usr/bin/dh-exec
debian/element-web-installer.d/README_configuration => /etc/element-web/README
debian/element-web-installer.d/element-web-installer /usr/sbin/
# source: https://packages.riot.im/element-release-key.gpg
# Retrieve key and apply ascii armor packaging:
# keyring=debian/element-web-installer.d/release-trustedkeys.gpg && echo -n >"$keyring" && curl -s "https://packages.riot.im/element-release-key.gpg" | gpg --no-default-keyring --keyring "$keyring" --import
debian/element-web-installer.d/release-trustedkeys.gpg => /usr/share/element-web-installer/trustedkeys.gpg
debian/element-web-installer.d/apache2/element-web.conf /etc/apache2/sites-available/
debian/element-web-installer.d/nginx/element-web /etc/nginx/sites-available/
#!/bin/sh
set -e
CONFIG_DIR=/etc/element-web
WEB_DIR=/var/lib/element-web-installer/htdocs
. /usr/share/debconf/confmodule
db_version 2.1
# debconf does not work with "set -u", thus we enable it after loading debconf
set -eu
ask_debconf_question() {
local question="$1"
local priority="$2"
local default_value="${3:-}"
local RET
if [ -n "$default_value" ] && ( ! db_get "$question" || [ -z "$RET" ] ); then
# the value is not configured via debconf, yet
db_set "$question" "$default_value"
fi
db_input "$priority" "$question" || true
# shellcheck disable=SC2119
db_go || true
db_get "$question" || true
printf '%s' "$RET"
}
reconfigure_config_json() {
local arg="$1"
jq "$arg" </etc/element-web/config.json | sponge /etc/element-web/config.json
}
configure_element() {
# determine webserver domain
local element_domain webserver_type homeserver_name homeserver_info
webserver_type=$(ask_debconf_question "element-web-installer/configure-webserver" "high")
if [ "$webserver_type" != "none" ]; then
element_domain=$(ask_debconf_question "element-web-installer/domain" "high" "$(hostname -f)")
fi
homeserver_name=$(ask_debconf_question "element-web-installer/matrix-homeserver-name" "high")
case "$webserver_type" in
apache2)
sed -i "s|ServerName.*$|ServerName $element_domain|g" /etc/apache2/sites-available/element-web.conf
if [ ! -e "/etc/apache2/sites-enabled/element-web.conf" ]; then
mkdir -p /etc/apache2/sites-enabled/
ln -s ../sites-available/element-web.conf /etc/apache2/sites-enabled/
if [ -x /usr/sbin/apache2 ]; then
service apache2 reload || true
fi
fi
;;
nginx)
sed -i "s|server_name .*$|server_name $element_domain;|g" /etc/nginx/sites-available/element-web
if [ ! -e "/etc/nginx/sites-enabled/element-web" ]; then
mkdir -p /etc/nginx/sites-enabled/
ln -s ../sites-available/element-web /etc/nginx/sites-enabled/
if [ -x /usr/sbin/nginx ]; then
service nginx reload || true
fi
fi
;;
none)
;;
*)
echo >&2 "Ignoring unknown webserver type for element-web: $webserver_type"
;;
esac
# discover the homeserver information
if homeserver_info="$(curl --silent --fail "https://$homeserver_name/.well-known/matrix/client")" \
&& [ -n "$homeserver_info" ] \
&& printf '%s' "$homeserver_info" | jq . >/dev/null 2>/dev/null; then
# inject the "server_name" if it is missing (it is not part of the well-known/matrix/client response)
if [ -z "$(printf '%s' "$homeserver_info" | jq -r '.["m.homeserver"].server_name // ""' >/dev/null)" ]; then
homeserver_info=$(printf '%s' "$homeserver_info" | jq '.["m.homeserver"].server_name |= "'"$homeserver_name"'"')
fi
reconfigure_config_json '.default_server_config |= '"$homeserver_info"
else
reconfigure_config_json '.default_server_config |= {"m.homeserver": {"base_url": "https://'"$homeserver_name"'", "server_name": "'"$homeserver_name"'"}}'
fi
# disable statistics gathering
reconfigure_config_json 'del (.piwik)'
reconfigure_config_json '.roomDirectory.servers |= ["'"$homeserver_name"'"]'
}
if [ "$1" = "configure" ]; then
/usr/sbin/element-web-installer upgrade
if [ ! -e "$CONFIG_DIR/config.json" ]; then
echo "Creating sample $CONFIG_DIR/config.json. Please adjust its content."
cp "$WEB_DIR/config.sample.json" "$CONFIG_DIR/config.json"
# create the symlink to config.json
/usr/sbin/element-web-installer apply-configuration
fi
configure_element
fi
set +eu
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
#!/bin/sh
set -eu
CONFIG_DIR=/etc/element-web
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
rm -f "$CONFIG_DIR/config.json"
rm -f /etc/apache2/sites-enabled/element-web.conf
rm -f /etc/nginx/sites-enabled/element-web
for directory in /etc/apache2/sites-enabled /etc/nginx/sites-enabled; do
if [ -d "$directory" ]; then
rmdir --parents --ignore-fail-on-non-empty "$directory"
fi
done
fi
set +eu
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
Template: element-web-installer/domain
Type: string
Description: Domain served by element-web:
Template: element-web-installer/configure-webserver
Type: select
Choices: none, apache2, nginx
Description: Configure a webserver?
Template: element-web-installer/matrix-homeserver-name
Type: string
Default: matrix.org
Description: Name of the default Matrix homeserver:
# a gnupg keyring for the element-web release key
# see debian/element-web-installer.install for its source
debian/element-web-installer.d/release-trustedkeys.gpg
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment