improvements to configure
This commit is contained in:
+196
-9
@@ -3,11 +3,30 @@
|
||||
TITLE="Federated Computer Core"
|
||||
DESCRIPTION="Superpanel, Nextcloud, email, files and Element"
|
||||
|
||||
# What you entered last time, so running this again only does what's missing
|
||||
# Each Core is in cores/<domain>.conf, with what you entered last time, so
|
||||
# running this again only does what's missing. core.conf is a copy of the main
|
||||
# Core's: Element, Tailscale and Backup use that one.
|
||||
CORE_CONF="$HOME/.config/coredesktop/core.conf"
|
||||
CORES_DIR="$HOME/.config/coredesktop/cores"
|
||||
TAILSCALE_CONF="$HOME/.config/coredesktop/tailscale.conf"
|
||||
BACKUP_CONF="$HOME/.config/coredesktop/backup.conf"
|
||||
GOA_ACCOUNT="$COREDESKTOP/configure.d/lib/goa-account"
|
||||
source "$COREDESKTOP/configure.d/lib/nextcloud.sh"
|
||||
[ -f "$CORE_CONF" ] && source "$CORE_CONF"
|
||||
MAIN_DOMAIN="$CORE_DOMAIN"
|
||||
|
||||
core_domains() {
|
||||
local file
|
||||
for file in "$CORES_DIR"/*.conf; do
|
||||
[ -f "$file" ] && basename "$file" .conf
|
||||
done
|
||||
}
|
||||
|
||||
load_core() {
|
||||
CORE_DOMAIN="" CORE_EMAIL="" CORE_NAME=""
|
||||
[ -n "$1" ] && source "$CORES_DIR/$1.conf"
|
||||
core_names
|
||||
}
|
||||
|
||||
# CORE_DOMAIN, CORE_EMAIL and CORE_NAME come from core.conf; the rest follow
|
||||
core_names() {
|
||||
@@ -48,19 +67,37 @@ element_done() {
|
||||
"$ELEMENT_CONFIG" &> /dev/null
|
||||
}
|
||||
|
||||
is_configured() {
|
||||
[ -n "$CORE_DOMAIN" ] || return 1
|
||||
core_names
|
||||
superpanel_done && nextcloud_done && email_done && files_done && element_done
|
||||
# Element only follows the main Core
|
||||
core_done() {
|
||||
superpanel_done && nextcloud_done && email_done && files_done \
|
||||
&& { [ "$CORE_DOMAIN" != "$MAIN_DOMAIN" ] || element_done; }
|
||||
}
|
||||
|
||||
# Done when every Core is
|
||||
is_configured() {
|
||||
local domain domains
|
||||
domains="$(core_domains)"
|
||||
[ -n "$domains" ] || return 1
|
||||
for domain in $domains; do
|
||||
(load_core "$domain" && core_done) || return 1
|
||||
done
|
||||
}
|
||||
|
||||
# The first Core you set up is the main one
|
||||
save_conf() {
|
||||
mkdir -p "$(dirname "$CORE_CONF")"
|
||||
mkdir -p "$CORES_DIR"
|
||||
{
|
||||
printf 'CORE_DOMAIN=%q\n' "$CORE_DOMAIN"
|
||||
printf 'CORE_EMAIL=%q\n' "$CORE_EMAIL"
|
||||
printf 'CORE_NAME=%q\n' "$CORE_NAME"
|
||||
} > "$CORE_CONF"
|
||||
} > "$CORES_DIR/$CORE_DOMAIN.conf"
|
||||
if [ -z "$MAIN_DOMAIN" ] || [ "$MAIN_DOMAIN" = "$CORE_DOMAIN" ]; then
|
||||
make_main "$CORE_DOMAIN"
|
||||
fi
|
||||
}
|
||||
|
||||
make_main() {
|
||||
cp "$CORES_DIR/$1.conf" "$CORE_CONF" && MAIN_DOMAIN="$1"
|
||||
}
|
||||
|
||||
desktop_entry() {
|
||||
@@ -263,7 +300,8 @@ step() {
|
||||
"setup_$name" || { echo -e "\e[31m$title was not set up.\e[0m"; STATUS=1; }
|
||||
}
|
||||
|
||||
run_configure() {
|
||||
# Set up the Core loaded with load_core, or a new one
|
||||
setup_core() {
|
||||
local url
|
||||
STATUS=0
|
||||
|
||||
@@ -304,7 +342,156 @@ run_configure() {
|
||||
step nextcloud "Nextcloud in Online Accounts"
|
||||
step email "Email in Online Accounts"
|
||||
step files "Nextcloud files at $MOUNT"
|
||||
element_installed && step element "Element with your Core's Matrix server"
|
||||
[ "$CORE_DOMAIN" = "$MAIN_DOMAIN" ] && element_installed \
|
||||
&& step element "Element with your Core's Matrix server"
|
||||
unset PASSWORD APP_PASSWORD
|
||||
return $STATUS
|
||||
}
|
||||
|
||||
# Tailscale and Backup point at one Core, which can't be removed while they do
|
||||
tailscale_on() {
|
||||
[ "$(source "$TAILSCALE_CONF" 2> /dev/null && echo "$TAILSCALE_DOMAIN")" = "$1" ] \
|
||||
&& tailscale status --json 2> /dev/null | jq -e '.BackendState == "Running"' > /dev/null
|
||||
}
|
||||
|
||||
backup_on() {
|
||||
[[ "$(source "$BACKUP_CONF" 2> /dev/null && echo "$BACKUP_WEBDAV")" == "https://nextcloud.$1/"* ]] \
|
||||
&& systemctl --user is-enabled -q coredesktop-backup.timer 2> /dev/null
|
||||
}
|
||||
|
||||
# Choose one of DOMAINS, other than $2 if given; sets PICKED
|
||||
pick_core() {
|
||||
local choices=() domain choice i
|
||||
for domain in "${DOMAINS[@]}"; do
|
||||
[ "$domain" != "$2" ] && choices+=("$domain")
|
||||
done
|
||||
if [ ${#choices[@]} -eq 1 ]; then
|
||||
PICKED="${choices[0]}"
|
||||
return 0
|
||||
fi
|
||||
for i in "${!choices[@]}"; do
|
||||
printf ' %d) %s\n' $((i + 1)) "${choices[$i]}"
|
||||
done
|
||||
read -rp "$1 " choice
|
||||
[[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= ${#choices[@]} )) || return 1
|
||||
PICKED="${choices[$((choice - 1))]}"
|
||||
}
|
||||
|
||||
# Point Element at the main Core, and say what else follows it
|
||||
main_changed() {
|
||||
load_core "$MAIN_DOMAIN"
|
||||
echo "$MAIN_DOMAIN is now your main Core."
|
||||
if element_installed && ! element_done && confirm_yes "Point Element at $MATRIX?"; then
|
||||
setup_element
|
||||
fi
|
||||
[ -f "$TAILSCALE_CONF" ] && echo "To move this computer to its Tailscale network: configure tailscale"
|
||||
[ -f "$BACKUP_CONF" ] && echo "To back up to it instead: configure backup"
|
||||
return 0
|
||||
}
|
||||
|
||||
# The app password this computer uses for the Core, from davfs2's secrets
|
||||
files_app_password() {
|
||||
grep -s "^$MOUNT " "$HOME/.davfs2/secrets" \
|
||||
| python3 -I -c 'import shlex, sys; print(shlex.split(sys.stdin.read())[2])' 2> /dev/null
|
||||
}
|
||||
|
||||
# Undo what setup_core did. Nothing on the Core itself changes.
|
||||
remove_core() {
|
||||
local domain="$1" new_main="" app_password mount_re
|
||||
if tailscale_on "$domain"; then
|
||||
echo "This computer is on $domain's Tailscale network. Leave it first: configure tailscale"
|
||||
return 1
|
||||
fi
|
||||
if backup_on "$domain"; then
|
||||
echo "Your backups go to $domain. Turn them off first: configure backup"
|
||||
return 1
|
||||
fi
|
||||
if [ "$domain" = "$MAIN_DOMAIN" ] && [ ${#DOMAINS[@]} -gt 1 ]; then
|
||||
echo "$domain is your main Core. Which Core should be the main one instead?"
|
||||
pick_core "Choose:" "$domain" || { echo "Choose a number from the list."; return 1; }
|
||||
new_main="$PICKED"
|
||||
fi
|
||||
echo "This removes $domain's Superpanel, Nextcloud, email and files from this computer."
|
||||
echo "Your files, email and everything else stay on the Core."
|
||||
confirm "Remove $domain?" || return 0
|
||||
|
||||
load_core "$domain"
|
||||
app_password="$(files_app_password)"
|
||||
[ -n "$app_password" ] && nextcloud_revoke_app_password "$app_password"
|
||||
|
||||
mountpoint -q "$MOUNT" && { umount "$MOUNT" 2> /dev/null || sudo umount "$MOUNT"; }
|
||||
mount_re="${MOUNT//./\\.}"
|
||||
if grep -qs " $MOUNT davfs " /etc/fstab; then
|
||||
sudo sed -i "\\# $mount_re davfs #d" /etc/fstab && sudo systemctl daemon-reload
|
||||
fi
|
||||
[ -d "$MOUNT" ] && sudo rmdir "$MOUNT" 2> /dev/null
|
||||
sed -i "\\#^$mount_re #d" "$HOME/.davfs2/secrets" 2> /dev/null
|
||||
sed -i "\\#^file://$mount_re #d" "$HOME/.config/gtk-3.0/bookmarks" 2> /dev/null
|
||||
rm -f "$HOME/.config/autostart/core-$CORE_DOMAIN-files.desktop"
|
||||
|
||||
"$GOA_ACCOUNT" remove owncloud "$CORE_USER@nextcloud.$CORE_DOMAIN"
|
||||
"$GOA_ACCOUNT" remove imap_smtp "$CORE_EMAIL"
|
||||
rm -f "$SUPERPANEL_DESKTOP" "$HOME/.local/share/icons/core-$CORE_DOMAIN-superpanel.png"
|
||||
|
||||
# Element keeps its default server, unless that was this Core
|
||||
if [ "$domain" = "$MAIN_DOMAIN" ] && [ -z "$new_main" ] && [ -f "$ELEMENT_CONFIG" ] \
|
||||
&& jq -e --arg name "matrix.$domain" '.default_server_config["m.homeserver"].server_name == $name' \
|
||||
"$ELEMENT_CONFIG" &> /dev/null; then
|
||||
jq 'del(.default_server_config)' "$ELEMENT_CONFIG" > "$ELEMENT_CONFIG.tmp" \
|
||||
&& mv -f "$ELEMENT_CONFIG.tmp" "$ELEMENT_CONFIG"
|
||||
fi
|
||||
|
||||
rm -f "$CORES_DIR/$domain.conf"
|
||||
echo "Removed $domain from this computer."
|
||||
if [ -n "$new_main" ]; then
|
||||
make_main "$new_main" && main_changed
|
||||
elif [ "$domain" = "$MAIN_DOMAIN" ]; then
|
||||
rm -f "$CORE_CONF"
|
||||
fi
|
||||
}
|
||||
|
||||
run_configure() {
|
||||
local choice i state
|
||||
mapfile -t DOMAINS < <(core_domains)
|
||||
if [ ${#DOMAINS[@]} -eq 0 ]; then
|
||||
load_core ""
|
||||
setup_core
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Your Cores:"
|
||||
for i in "${!DOMAINS[@]}"; do
|
||||
if (load_core "${DOMAINS[$i]}" && core_done); then
|
||||
state="\e[32mdone\e[0m "
|
||||
else
|
||||
state="\e[33mto do\e[0m"
|
||||
fi
|
||||
printf " %d) $state %s%s\n" $((i + 1)) "${DOMAINS[$i]}" \
|
||||
"$([ "${DOMAINS[$i]}" = "$MAIN_DOMAIN" ] && echo " (main)")"
|
||||
done
|
||||
echo
|
||||
echo " Choose a number to finish or change its setup, or:"
|
||||
echo " a) Add a Core"
|
||||
[ ${#DOMAINS[@]} -gt 1 ] && echo " m) Make another Core the main one"
|
||||
echo " r) Remove a Core"
|
||||
echo " q) Leave it as it is"
|
||||
echo
|
||||
read -rp "Choose: " choice
|
||||
case "$choice" in
|
||||
a|A)
|
||||
load_core ""
|
||||
setup_core ;;
|
||||
m|M)
|
||||
[ ${#DOMAINS[@]} -gt 1 ] || return 0
|
||||
pick_core "Which should be the main one?" "$MAIN_DOMAIN" || { echo "Choose a number from the list."; return 1; }
|
||||
make_main "$PICKED" && main_changed ;;
|
||||
r|R)
|
||||
pick_core "Which Core should be removed?" || { echo "Choose a number from the list."; return 1; }
|
||||
remove_core "$PICKED" ;;
|
||||
*)
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= ${#DOMAINS[@]} )); then
|
||||
load_core "${DOMAINS[$((choice - 1))]}"
|
||||
setup_core
|
||||
fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user