diff --git a/bluesky/actions/new-invite b/bluesky/actions/new-invite new file mode 100755 index 0000000..2c4ae3f --- /dev/null +++ b/bluesky/actions/new-invite @@ -0,0 +1,98 @@ +#!/bin/bash +## compose: no-hooks + +if [ -z "$SERVICE_DATASTORE" ]; then + echo "This script is meant to be run through 'compose' to work properly." >&2 + exit 1 +fi + + +. $CHARM_PATH/lib/common + + +version=0.1 +usage="$exname [-h|--help]" +help=" +USAGE: + +$usage + +DESCRIPTION: + +Request an invite code. + +EXAMPLES: + + $exname + +" + + +dbname= +neutralize= +while [ "$1" ]; do + case "$1" in + "--help"|"-h") + print_help >&2 + exit 0 + ;; + --*|-*) + err "Unexpected optional argument '$1'" + print_usage >&2 + exit 1 + ;; + *) + err "Unexpected positional argument '$1'" + print_usage >&2 + exit 1 + ;; + esac + shift +done + + +set -e + +. "$PDS_ENV_FILE" + + +curl_opts=() + +container_network_ip=$(get_healthy_container_ip_for_service "$SERVICE_NAME" 3000 4) || { + err "Please ensure that $DARKYELLOW$service$NORMAL is running before using '$exname'." + exit 1 +} + +container_ip=${container_network_ip##*:} +container_network=${container_network_ip%%:*} + + +DEFAULT_CURL_IMAGE=${DEFAULT_CURL_IMAGE:-docker.0k.io/curl} + +cmd=( + docker run -i --rm --network "$container_network" + "$DEFAULT_CURL_IMAGE" + --fail \ + --silent \ + --show-error \ + --request POST \ + --user "admin:${PDS_ADMIN_PASSWORD}" \ + --header "Content-Type: application/json" \ + --data '{"useCount": 1}' \ + "http://${container_ip}:3000/xrpc/com.atproto.server.createInviteCode" + ) + +## XXXvlab: contains password, left only for advanced debug +#echo "COMMAND: ${cmd[@]}" >&2 + +if ! out=$("${cmd[@]}"); then + err "Failed to request an invite code." + echo " $out" | prefix " $GRAY|$NORMAL " >&2 + exit 1 +fi + +e "$out" | jq -r '.code' || { + err "Failed to parse invite code from response." + echo " $out" | prefix " $GRAY|$NORMAL " >&2 + exit 1 +} diff --git a/bluesky/hooks/init b/bluesky/hooks/init new file mode 100755 index 0000000..b18d82c --- /dev/null +++ b/bluesky/hooks/init @@ -0,0 +1,7 @@ +#!/bin/bash + +. lib/common + +set -e + +bluesky:init diff --git a/bluesky/hooks/web_proxy-relation-joined b/bluesky/hooks/web_proxy-relation-joined new file mode 100755 index 0000000..d3c9e86 --- /dev/null +++ b/bluesky/hooks/web_proxy-relation-joined @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +DOMAIN=$(relation-get domain) || exit 1 + +config-add "\ +services: + $MASTER_BASE_SERVICE_NAME: + environment: + PDS_HOSTNAME: $DOMAIN +" diff --git a/bluesky/lib/common b/bluesky/lib/common new file mode 100644 index 0000000..cc2c2ea --- /dev/null +++ b/bluesky/lib/common @@ -0,0 +1,67 @@ +# -*- mode: shell-script -*- + +PDS_LOCAL_DATADIR=/var/lib/bluesky +PDS_DATADIR="$SERVICE_DATASTORE$PDS_LOCAL_DATADIR" +PDS_ENV_FILE="$PDS_DATADIR/.env" + + +bluesky:init() { + local admin_password + init-config-add " +$SERVICE_NAME: + env_file: + - \"$PDS_ENV_FILE\" +" + + [ -e "$PDS_ENV_FILE" ] && return + + admin_password=$(password:get admin internal) || { + err "Failed to get admin password" >&2 + return 1 + } + mkdir -p "${PDS_ENV_FILE%/*}" + + if ! plc_key=$(openssl ecparam --name secp256k1 --genkey --noout --outform DER 2>&1); then + err "Failed to generate PLC key" >&2 + e "$plc_key" | prefix " $GRAY|$NORMAL " >&2 + return 1 + fi + if ! plc_key=$(set -o pipefail + echo "$plc_key" | + tail --bytes=+8 | + head --bytes=32 | + xxd --plain --cols 32 2>&1 + ); then + err "Failed to extract PLC key" >&2 + e "$plc_key" | prefix " $GRAY|$NORMAL " >&2 + return 1 + fi + + if ! jwt_secret=$(openssl rand -hex 16); then + err "Failed to generate JWT secret" >&2 + e "$jwt_secret" | prefix " $GRAY|$NORMAL " >&2 + return 1 + fi + + cat > "$PDS_ENV_FILE" <