remove legacy asteroids script, go scaffold, agent report

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 13:30:34 +01:00
parent 4cbfd92dad
commit ac76bb95f4
13 changed files with 1 additions and 579 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/target/
.DS_Store

View File

@@ -1,46 +0,0 @@
# AI Agent Report — uberspace-cli
## Status
Phase 1 + 2 of the Rust rewrite are complete. The `uc` binary compiles and all 24 unit tests pass.
## What was done
- Created Rust project (`Cargo.toml`, binary name `uc`, CalVer `2026.3.3`)
- Implemented all Phase 1 + 2 modules:
- `registry.rs` — TOML-based asteroid CRUD (`~/.config/uc/registry.toml`)
- `ssh.rs` — passthrough (`ssh -t`) and capture (for status collection)
- `cache.rs` — per-asteroid TOML status cache (`~/.config/uc/cache/*.toml`)
- `translate.rs` — v7/v8 command translation (mail, port, tools, web backend)
- `status.rs` — remote status collection via SSH, colored display, age/staleness
- `cli.rs` — clap-derived CLI with fallback to asteroid passthrough
- `uc import <path>` migrates legacy `asteroids.list` + cache files
## CLI command tree
```
uc add <name> <server> <version> # register asteroid
uc list # list registered
uc remove <name> # deregister
uc status [--refresh] # aggregate from cache (or refresh all)
uc <name> status # refresh + show one asteroid
uc <name> <args...> # passthrough → SSH with v7/v8 translation
uc import <path> # migrate from asteroids.list
```
## Architecture notes
- Clap `try_parse()` + manual fallback handles the `uc <name> <args...>` passthrough pattern
- SSH passthrough preserves the user's SSH config/keys — no Rust SSH library needed
- Remote status script is the same bash heredoc from the original, embedded as a const
- v8 Rich-table box-drawing chrome is stripped by the remote script before parsing
## What's next (Phase 3)
- Dashboard HTTP API: `reqwest` + `serde_json` for login, create-asteroid, add-ssh-key, delete
- Session management: cookies + CSRF token in `~/.config/uc/session.toml`
## Known considerations
- The `cache::load()` function exists but is currently only used transitively via `load_all()` — produces a dead-code warning
- Edition 2024 requires Rust 1.85+; current toolchain is 1.93

View File

@@ -1,452 +0,0 @@
#!/usr/bin/env bash
# asteroids — Uberspace account inventory, status, SSH passthrough
# Lives in tools/asteroids/. Symlink to ~/.bin/asteroids via Ansible bin role.
set -euo pipefail
# --- Resolve repo root (follows symlinks) ---
_src="${BASH_SOURCE[0]}"
while [ -L "$_src" ]; do
_dir="$(cd "$(dirname "$_src")" && pwd -P)"
_src="$(readlink "$_src")"
[[ "$_src" != /* ]] && _src="$_dir/$_src"
done
_TOOL_DIR="$(cd "$(dirname "$_src")" && pwd -P)"
_REPO_DIR="$(cd "$_TOOL_DIR/../.." && pwd -P)"
unset _src _dir
# --- Config paths ---
UBERSPACES_REGISTRY="$_TOOL_DIR/asteroids.list"
UBERSPACE_CACHE_DIR="$_TOOL_DIR/cache"
# --- Colors ---
if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then
C_RESET=$'\033[0m'
C_BOLD=$'\033[1m'
C_DIM=$'\033[2m'
C_CYAN=$'\033[36m'
C_BLUE=$'\033[34m'
C_GREEN=$'\033[32m'
C_YELLOW=$'\033[33m'
C_RED=$'\033[31m'
else
C_RESET="" C_BOLD="" C_DIM="" C_CYAN="" C_BLUE="" C_GREEN="" C_YELLOW="" C_RED=""
fi
# --- Print helpers ---
_info() { printf "%b==>%b %s\n" "$C_CYAN" "$C_RESET" "$*"; }
_ok() { printf "%b[ok]%b %s\n" "$C_GREEN" "$C_RESET" "$*"; }
_warn() { printf "%b[warn]%b %s\n" "$C_YELLOW" "$C_RESET" "$*" >&2; }
_error() { printf "%b[error]%b %s\n" "$C_RED" "$C_RESET" "$*" >&2; }
# --- Labeled field with tree formatting for multi-value (comma-separated) fields ---
_print_field() {
local label="$1" value="$2"
local -a items=()
[[ -n "$value" ]] && IFS=',' read -ra items <<< "$value"
local n="${#items[@]}"
if [[ "$n" -eq 0 ]]; then
printf " %b%-9s%b (none)\n" "$C_DIM" "$label" "$C_RESET"
elif [[ "$n" -eq 1 ]]; then
printf " %b%-9s%b %s\n" "$C_DIM" "$label" "$C_RESET" "${items[0]}"
else
printf " %b%-9s%b ├── %s\n" "$C_DIM" "$label" "$C_RESET" "${items[0]}"
local i
for (( i=1; i<n-1; i++ )); do
printf " %b%-9s%b │ %s\n" "$C_DIM" "" "$C_RESET" "${items[$i]}"
done
printf " %b%-9s%b └── %s\n" "$C_DIM" "" "$C_RESET" "${items[$((n-1))]}"
fi
}
# --- Print one account status block ---
# Args: name server version ports web mdom musr time_plain time_display
# time_plain: plain text used for right-alignment width calculation
# time_display: same string, but may contain ANSI color codes
_print_account_block() {
local name="$1" server="$2" version="$3"
local ports="$4" web="$5" mdom="$6" musr="$7"
local time_plain="$8" time_display="$9"
local ports_label musr_label
if [[ "$version" == "8" ]]; then
ports_label="backends"; musr_label="addrs"
else
ports_label="ports"; musr_label="users"
fi
local ver_display=""
[[ -n "$version" && "$version" != "?" ]] && ver_display=" u${version}"
# Header: bold name, dim server+version, time_display right-aligned to col 78
local left_plain=" ${name} ${server}${ver_display}"
local pad=$(( 78 - ${#left_plain} - ${#time_plain} ))
(( pad < 1 )) && pad=1
printf " %b%s%b %b%s%s%b%*s%s\n" \
"$C_BOLD" "$name" "$C_RESET" \
"$C_DIM" "$server" "$ver_display" "$C_RESET" \
"$pad" "" \
"$time_display"
_print_field "$ports_label" "$ports"
_print_field "web" "$web"
_print_field "mail" "$mdom"
_print_field "$musr_label" "$musr"
}
# --- File helpers ---
_file_remove_where_first_field_equals() {
local file="$1"
local field_value="$2"
local tmp_file
tmp_file=$(mktemp)
awk -v v="$field_value" '$1 != v' "$file" > "$tmp_file"
mv "$tmp_file" "$file"
}
# --- Registry bootstrap ---
_ensure_registry() {
mkdir -p "$(dirname "$UBERSPACES_REGISTRY")"
touch "$UBERSPACES_REGISTRY"
mkdir -p "$UBERSPACE_CACHE_DIR"
}
# --- Usage ---
usage() {
cat <<-EOF
asteroids — Uberspace account manager
Usage: asteroids <command> [args]
Inventory:
add <name> <server> <version> Register an account (version: 7 or 8)
list|ls Show all registered accounts
remove|rm <name> Deregister an account
Status:
status Aggregate overview from local cache
status --refresh Refresh all accounts via SSH, then show summary
<name> status Refresh + show status for one account (SSH)
Passthrough:
<name> <subcommand...> Run any uberspace subcommand via SSH
Examples:
asteroids add danger cetus.uberspace.de 7
asteroids add impstr pandora.uberspace.de 8
asteroids list
asteroids danger status
asteroids danger mail domain list
asteroids danger web backend list
asteroids danger port add
EOF
}
# --- Inventory commands ---
cmd_add() {
local name="$1"
local server="$2"
local version="${3:-}"
_ensure_registry
_file_remove_where_first_field_equals "$UBERSPACES_REGISTRY" "$name"
printf "%s %s %s\n" "$name" "$server" "$version" >> "$UBERSPACES_REGISTRY"
local ver_info=""
[[ -n "$version" ]] && ver_info=" (u${version})"
_ok "Registered: $name @ $server${ver_info}"
}
cmd_list() {
_ensure_registry
if ! awk '!/^[[:space:]]*#/ && NF >= 2 { found=1; exit } END { exit !found }' "$UBERSPACES_REGISTRY"; then
_warn "No accounts registered. Use: asteroids add <name> <server> <version>"
return 0
fi
printf " %b%-12s %-28s %s%b\n" "$C_BOLD" "NAME" "SERVER" "VER" "$C_RESET"
printf "%b%s%b\n" "$C_DIM" "$(printf '─%.0s' $(seq 1 49))" "$C_RESET"
awk '!/^[[:space:]]*#/ && NF >= 2 { printf " %-12s %-28s %s\n", $1, $2, ($3 ? "u"$3 : "?") }' "$UBERSPACES_REGISTRY"
}
cmd_remove() {
local name="$1"
_ensure_registry
if ! awk -v n="$name" '$1 == n { found=1; exit } END { exit !found }' "$UBERSPACES_REGISTRY"; then
_error "'$name' not found in registry."
return 1
fi
_file_remove_where_first_field_equals "$UBERSPACES_REGISTRY" "$name"
rm -f "$UBERSPACE_CACHE_DIR/$name"
_ok "Removed: $name"
}
# --- Lookup ---
_lookup() {
local name="$1"
local server
server=$(awk -v n="$name" '!/^[[:space:]]*#/ && $1 == n { print $2; exit }' "$UBERSPACES_REGISTRY")
if [[ -z "$server" ]]; then
_error "'$name' not found in registry."
return 1
fi
printf '%s\n' "$server"
}
_lookup_version() {
local name="$1"
awk -v n="$name" '!/^[[:space:]]*#/ && $1 == n { print ($3 ? $3 : "?"); exit }' "$UBERSPACES_REGISTRY"
}
# --- SSH passthrough ---
_ssh_passthrough() {
local name="$1"
shift
local server
server=$(_lookup "$name") || return 1
ssh -t -o BatchMode=no "$name@$server" "$@"
}
# --- Per-account status (live SSH refresh) ---
cmd_status_one() {
local name="$1"
local server
server=$(_lookup "$name") || return 1
_info "Refreshing status for $name @ $server ..."
local updated version
updated=$(date -u '+%Y-%m-%dT%H:%M:%S')
version=$(_lookup_version "$name")
local raw=""
if ! raw=$(ssh -o BatchMode=no "$name@$server" bash -s "$version" <<'ENDSSH'
version="$1"
set +e +u
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
# bash -s is non-interactive, non-login: .bashrc/.profile are not sourced,
# so PATH may be minimal. Extend it to cover all standard system locations.
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$HOME/bin:$HOME/.local/bin:$PATH"
# All data fetched in parallel. Each job gets stdin from /dev/null to prevent
# them from racing on the shared heredoc stdin (which causes silent failures
# when the uberspace CLI reads from stdin for config/token checks).
if [[ "$version" == "8" ]]; then
uberspace web backend list </dev/null > "$tmpdir/ports" 2>"$tmpdir/e.ports" &
else
uberspace port list </dev/null > "$tmpdir/ports" 2>"$tmpdir/e.ports" &
fi
uberspace web domain list </dev/null > "$tmpdir/web" 2>"$tmpdir/e.web" &
uberspace mail domain list </dev/null > "$tmpdir/mdom" 2>"$tmpdir/e.mdom" &
if [[ "$version" == "8" ]]; then
uberspace mail address list </dev/null > "$tmpdir/musr" 2>"$tmpdir/e.musr" &
else
uberspace mail user list </dev/null > "$tmpdir/musr" 2>"$tmpdir/e.musr" &
fi
wait
# Emit any command errors to stderr — they flow to the user's terminal.
for _ef in "$tmpdir"/e.*; do
[ -s "$_ef" ] && cat "$_ef" >&2
done
# parse_list: strips v8 Rich-table chrome (box-drawing separator rows +
# column header) while leaving v7 plain-text output untouched.
# Uses the 2-byte UTF-8 prefix of U+25xx box-drawing chars (\xe2\x94)
# instead of a literal char to avoid locale issues on the remote host.
parse_list() {
local f="$1"
[ -s "$f" ] || return 0
if grep -q $'\xe2\x94' "$f" 2>/dev/null; then
grep -v $'\xe2\x94' "$f" \
| awk 'NR==1{next} /^[[:space:]]*$/{next} {gsub(/^[[:space:]]+|[[:space:]]+$/,""); print}'
else
grep -v '^[[:space:]]*$' "$f"
fi
}
ports=$(parse_list "$tmpdir/ports" | tr '\n' ',' | sed 's/,$//')
web=$(parse_list "$tmpdir/web" | tr '\n' ',' | sed 's/,$//')
mdom=$(parse_list "$tmpdir/mdom" | tr '\n' ',' | sed 's/,$//')
musr=$(parse_list "$tmpdir/musr" | tr '\n' ',' | sed 's/,$//')
printf 'VERSION=%s\n' "${version:-?}"
printf 'PORTS=%s\n' "$ports"
printf 'WEB=%s\n' "$web"
printf 'MDOM=%s\n' "$mdom"
printf 'MUSR=%s\n' "$musr"
ENDSSH
); then
_error "SSH connection to $name @ $server failed."
return 1
fi
local ports web mdom musr
ports=$(printf '%s\n' "$raw" | awk '/^PORTS=/{sub(/^PORTS=/,""); print; exit}' | tr -d '\r')
web=$(printf '%s\n' "$raw" | awk '/^WEB=/{sub(/^WEB=/,""); print; exit}' | tr -d '\r')
mdom=$(printf '%s\n' "$raw" | awk '/^MDOM=/{sub(/^MDOM=/,""); print; exit}' | tr -d '\r')
musr=$(printf '%s\n' "$raw" | awk '/^MUSR=/{sub(/^MUSR=/,""); print; exit}' | tr -d '\r')
# If nothing came back at all, the remote commands likely couldn't run.
if [[ -z "$ports" && -z "$web" && -z "$mdom" && -z "$musr" ]]; then
_warn "No data from $name — check stderr above, or run manually:"
printf " ssh %s@%s 'which uberspace && uberspace --version'\n" "$name" "$server" >&2
fi
mkdir -p "$UBERSPACE_CACHE_DIR"
{
printf 'UPDATED=%s\n' "$updated"
printf 'NAME=%s\n' "$name"
printf 'SERVER=%s\n' "$server"
printf 'VERSION=%s\n' "$version"
printf 'PORTS=%s\n' "$ports"
printf 'WEB_DOMAINS=%s\n' "$web"
printf 'MAIL_DOMAINS=%s\n' "$mdom"
printf 'MAIL_USERS=%s\n' "$musr"
} > "$UBERSPACE_CACHE_DIR/$name"
printf '\n'
_print_account_block "$name" "$server" "$version" \
"$ports" "$web" "$mdom" "$musr" \
"$updated" "${C_DIM}${updated}${C_RESET}"
}
# --- Aggregate status (from cache, or --refresh to repopulate) ---
cmd_status_all() {
local refresh=false
while [[ $# -gt 0 ]]; do
case "$1" in
--refresh) refresh=true ;;
*) _error "Unknown option: $1"; return 1 ;;
esac
shift
done
_ensure_registry
if $refresh; then
local names=()
while IFS= read -r line; do
[[ "$line" =~ ^[[:space:]]*# || -z "${line// }" ]] && continue
names+=("${line%% *}")
done < "$UBERSPACES_REGISTRY"
if [[ "${#names[@]}" -eq 0 ]]; then
_warn "No accounts registered. Use: asteroids add <name> <server>"
return 0
fi
for n in "${names[@]}"; do
cmd_status_one "$n" || true
done
return 0
fi
local found=0
for f in "$UBERSPACE_CACHE_DIR"/*; do [[ -f "$f" ]] && found=1 && break; done
if [[ "$found" -eq 0 ]]; then
_warn "No cached status — last refresh: never"
printf " Run: %basteroids status --refresh%b\n" "$C_BLUE" "$C_RESET" >&2
return 0
fi
local now stale_count=0 first=1
now=$(date -u '+%s')
for cache in "$UBERSPACE_CACHE_DIR"/*; do
[[ -f "$cache" ]] || continue
local name="" server="" version="" ports="" web="" mdom="" musr="" updated=""
while IFS= read -r line; do
case "$line" in
NAME=*) name="${line#NAME=}" ;;
SERVER=*) server="${line#SERVER=}" ;;
VERSION=*) version="${line#VERSION=}" ;;
PORTS=*) ports="${line#PORTS=}" ;;
WEB_DOMAINS=*) web="${line#WEB_DOMAINS=}" ;;
MAIL_DOMAINS=*) mdom="${line#MAIL_DOMAINS=}" ;;
MAIL_USERS=*) musr="${line#MAIL_USERS=}" ;;
UPDATED=*) updated="${line#UPDATED=}" ;;
esac
done < "$cache"
local age_str="unknown" age_secs=0
if [[ -n "$updated" ]]; then
local epoch=""
epoch=$(date -u -d "$updated" '+%s' 2>/dev/null \
|| date -u -j -f '%Y-%m-%dT%H:%M:%S' "$updated" '+%s' 2>/dev/null \
|| true)
if [[ -n "$epoch" ]]; then
age_secs=$(( now - epoch ))
if (( age_secs < 60 )); then age_str="${age_secs}s ago"
elif (( age_secs < 3600 )); then age_str="$(( age_secs / 60 ))m ago"
elif (( age_secs < 86400 )); then age_str="$(( age_secs / 3600 ))h ago"
else age_str="$(( age_secs / 86400 ))d ago"
fi
(( age_secs >= 86400 )) && (( stale_count++ )) || true
else
age_str="$updated"
fi
fi
local time_plain="$age_str" time_display="${C_DIM}${age_str}${C_RESET}"
if (( age_secs >= 86400 )); then
time_plain="${age_str} !"
time_display="${C_DIM}${age_str} ${C_RESET}${C_YELLOW}!${C_RESET}"
fi
[[ "$first" -eq 0 ]] && printf '\n'
first=0
_print_account_block "$name" "$server" "$version" \
"$ports" "$web" "$mdom" "$musr" \
"$time_plain" "$time_display"
done
if (( stale_count > 0 )); then
printf '\n'
_warn "${stale_count} account(s) have stale cache (>24h) — run: asteroids status --refresh"
fi
}
# --- Dispatch ---
if [[ $# -eq 0 ]]; then
usage; exit 0
fi
case "$1" in
add)
shift
if [[ $# -lt 3 ]]; then
printf "%bUsage:%b asteroids add <name> <server> <version>\n" "$C_BLUE" "$C_RESET" >&2
printf " Example: asteroids add danger cetus.uberspace.de 7\n" >&2
exit 1
fi
cmd_add "$1" "$2" "$3"
;;
list|ls)
cmd_list
;;
remove|rm)
shift
if [[ $# -lt 1 ]]; then
printf "%bUsage:%b asteroids remove <name>\n" "$C_BLUE" "$C_RESET" >&2
exit 1
fi
cmd_remove "$1"
;;
status)
shift
cmd_status_all "$@"
;;
help|-h|--help)
usage
;;
*)
# Named account: asteroids <name> [status | <subcommand...>]
_name="$1"; shift
_ensure_registry
_lookup "$_name" > /dev/null || exit 1
if [[ "${1:-}" == "status" ]]; then
cmd_status_one "$_name"
else
_ssh_passthrough "$_name" uberspace "$@"
fi
;;
esac

View File

@@ -1,9 +0,0 @@
# name server
danger cetus.uberspace.de 7
serve prospero.uberspace.de 8
impstr pandora.uberspace.de 8
foertsch cressida.uberspace.de 7
jef caliban.uberspace.de 7
kristina tucana.uberspace.de 7
suprblox vega.uberspace.de 7
wtp larissa.uberspace.de 8

View File

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:31:06
NAME=danger
SERVER=cetus.uberspace.de
VERSION=7
QUOTA=
PORTS=
WEB_DOMAINS=danger.uber.space,rhqq2.de,ws.rhqq2.de
MAIL_DOMAINS=danger.uber.space,rhqq2.de
MAIL_USERS=No mailboxes found.

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:31:26
NAME=foertsch
SERVER=cressida.uberspace.de
VERSION=7
QUOTA=
PORTS=
WEB_DOMAINS=ampelkarten.de,arctic-law.com,doedde.de,foertsch.uber.space,juicyshop.de,newvendo.de,shop.juicyshop.de,themenundtexte.de,tomis-motorradshop.de,undrowear.de,www.juicyshop.de,www.undrowear.de,xn--ddde-5qa.de,xn--frtsch-wxa.de
MAIL_DOMAINS=ampelkarten.de,arctic-law.com,foertsch.uber.space,netfelix.jetzt,themenundtexte.de,xn--frtsch-wxa.de
MAIL_USERS=conrad,felix,hermes,hermine,juicy,paul,support,vmunde

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:31:24
NAME=impstr
SERVER=pandora.uberspace.de
VERSION=8
QUOTA=
PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /StiggerDLBot PORT 8001 remove,* /movie APACHE None keep
WEB_DOMAINS=Domain,impstr.uber.space
MAIL_DOMAINS=Domain Alias of DNS state,impstr.uber.space VALID
MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse impstr.u… no no yes sysmail@i…,hostmaster impstr.u… no no yes sysmail@i…,postmaster impstr.u… no no yes sysmail@i…,sysmail impstr.u… yes no no uberspac…

9
asteroids/cache/jef vendored
View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:31:42
NAME=jef
SERVER=caliban.uberspace.de
VERSION=7
QUOTA=
PORTS=
WEB_DOMAINS=bitwarden.jef-sachsen.de,email.jef-sachsen.de,eud-sachsen.de,eurom.at,jef-leipzig.de,jef-sachsen.de,jef.uber.space,mail.jef-sachsen.de,newsletter.jef-sachsen.de
MAIL_DOMAINS=eud-sachsen.de,eurom.at,jef-leipzig.de,jef-sachsen.de,jef.uber.space,mail.jef-sachsen.de
MAIL_USERS=+,abuse,admin,annika.fleischer,anton.hussing,bitwarden,bjoern.donath,catchall,emely.schaefer,fabian.brueder,felix.foertsch,finnja.klinger,hannes.lauter,hostmaster,info,johannes.kropp,klaas.wibker,kontakt,kristina.oertel,laura.greiff,laurenz.frenzel,maria-teresa.roelke,natalie.semin,no-reply,nora.sandner,paula.kirchner,postmaster,susan.wolf,tanja.schmidt,tim.meglitsch,vincent.kaienburg,vorstand

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:32:10
NAME=kristina
SERVER=tucana.uberspace.de
VERSION=7
QUOTA=
PORTS=
WEB_DOMAINS=kristina.uber.space,kristinaschoenfeldt.de
MAIL_DOMAINS=kristina.uber.space,kristinaschoenfeldt.de
MAIL_USERS=mail,noreply

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:31:22
NAME=serve
SERVER=prospero.uberspace.de
VERSION=8
QUOTA=
PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /sticker-cloner PORT 8080 remove
WEB_DOMAINS=Domain,serve.uber.space
MAIL_DOMAINS=Domain Alias of DNS state,serve.uber.space VALID
MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse serve.ub… no no yes sysmail@s…,hostmaster serve.ub… no no yes sysmail@s…,postmaster serve.ub… no no yes sysmail@s…,sysmail serve.ub… yes no no uberspac…

View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:32:28
NAME=suprblox
SERVER=vega.uberspace.de
VERSION=7
QUOTA=
PORTS=
WEB_DOMAINS=superblocks-leipzig.de,suprblox.de,suprblox.uber.space,www.superblocks-leipzig.de
MAIL_DOMAINS=suprblox.de,suprblox.uber.space
MAIL_USERS=No mailboxes found.

9
asteroids/cache/wtp vendored
View File

@@ -1,9 +0,0 @@
UPDATED=2026-02-25T17:32:45
NAME=wtp
SERVER=larissa.uberspace.de
VERSION=8
QUOTA=
PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /api PORT 3000 remove
WEB_DOMAINS=Domain,wtp.uber.space
MAIL_DOMAINS=Domain Alias of DNS state,wtp.uber.space VALID
MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse wtp.uber… no no yes sysmail@w…,hostmaster wtp.uber… no no yes sysmail@w…,postmaster wtp.uber… no no yes sysmail@w…,sysmail wtp.uber… yes no no uberspac…