diff --git a/README.md b/README.md index f59d412..46b1225 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,17 @@ -A collection of Ham Radio server utilities to transform CoreServer machines in to Ham Radio servers. +A collection of Ham Radio server utilities to transform [CoreDesktop](https://gitea.federated.computer/Federated_Computer/coredesktop) machines in to Ham Radio servers. -Update here. +## Installation + +HamPackServer is a CoreDesktop sibling project. With CoreDesktop installed, run: ``` -wget -qO- https://gitea.young.computer/david/hampackserver/raw/branch/main/install.sh | bash +sibling add https://gitea.young.computer/david/HamPackServer.git ``` + +This clones HamPackServer into `~/.local/share/siblings/HamPackServer` and runs its `install.sh`. From then on, CoreDesktop's `update` command pulls HamPackServer and runs its `update.sh`, so HamPackServer stays current along with the rest of the system. Re-run the `sibling add` command above to repair an install. + +`update` never prompts. If it can't tell which version of a compiled server is installed, it skips that server; re-run the `sibling add` command above to be asked whether to build it. + +To see whether newer versions of the compiled servers are available, run `hampackservercheck`. + +If you installed HamPackServer before it became a sibling project, run the `sibling add` command above once. It moves HamPackServer to the new location and removes the old `hampackserverupdate` and `hampackserverrefresh` commands. diff --git a/fix-networking.sh b/fix-networking.sh index 1f000ba..c89ca4c 100644 --- a/fix-networking.sh +++ b/fix-networking.sh @@ -5,7 +5,7 @@ set -e echo "Installing Avahi and nss-mdns..." -sudo pacman -S --noconfirm avahi nss-mdns +sudo pacman -S --needed --noconfirm avahi nss-mdns echo "Enabling Avahi daemon..." sudo systemctl enable avahi-daemon.service diff --git a/hampackservercheck b/hampackservercheck index 2cfa56d..e9038b2 100755 --- a/hampackservercheck +++ b/hampackservercheck @@ -1,6 +1,12 @@ #!/bin/bash -CONF="compile.conf" +SCRIPT_DIR=$(dirname "$(realpath "$0")") +# Installed in ~/.local/bin, this finds the repo where `sibling` cloned it +if [ ! -f "$SCRIPT_DIR/compile.conf" ]; then + SCRIPT_DIR="$HOME/.local/share/siblings/HamPackServer" +fi +HAMPACKSERVER_DIR="${HAMPACKSERVER_DIR:-$SCRIPT_DIR}" +CONF="$HAMPACKSERVER_DIR/compile.conf" if [ ! -f "$CONF" ]; then echo "Error: compile.conf not found at $CONF" diff --git a/hampackserverrefresh b/hampackserverrefresh deleted file mode 100755 index 6ab1036..0000000 --- a/hampackserverrefresh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -# Print the logo -print_logo() { - cat << "EOF" - - ██╗ ██╗ █████╗ ███╗ ███╗██████╗ █████╗ ██████╗██╗ ██╗ - ██║ ██║██╔══██╗████╗ ████║██╔══██╗██╔══██╗██╔════╝██║ ██╔╝ - ███████║███████║██╔████╔██║██████╔╝███████║██║ █████╔╝ - ██╔══██║██╔══██║██║╚██╔╝██║██╔═══╝ ██╔══██║██║ ██╔═██╗ - ██║ ██║██║ ██║██║ ╚═╝ ██║██║ ██║ ██║╚██████╗██║ ██╗ - ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ - - ███████╗███████╗██████╗ ██╗ ██╗███████╗██████╗ - ██╔════╝██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗ - ███████╗█████╗ ██████╔╝██║ ██║█████╗ ██████╔╝ - ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██╔══╝ ██╔══██╗ - ███████║███████╗██║ ██║ ╚████╔╝ ███████╗██║ ██║ - ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝ - - - -EOF -} - -# Clear screen and show logo -clear -print_logo - -echo "Let's get the lastest changes to HamPack..." - -wget -qO- https://gitea.young.computer/david/HamPackServer/raw/branch/main/install.sh | bash - -# Check whether the running kernel matches the installed modules — if not, a -# newer kernel was installed during this run and a reboot is required -if ! ls /usr/lib/modules/$(uname -r) > /dev/null 2>&1; then - echo "A newer kernel has been installed, a reboot is recommended." - read -rp "Reboot now? [y/N] " response - case "$response" in - [yY][eE][sS]|[yY]) - echo "Rebooting..." - sudo reboot - ;; - *) - echo "Reboot skipped. Please remember to reboot when convenient." - exit 0 - ;; - esac -else - echo "Kernel is up to date, no reboot needed. You may want to consider a reboot if other significant software was updated or installed." -fi diff --git a/hampackserverupdate b/hampackserverupdate deleted file mode 100755 index d02a9b8..0000000 --- a/hampackserverupdate +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash - -# Print the logo -print_logo() { - cat << "EOF" - - ██╗ ██╗ █████╗ ███╗ ███╗██████╗ █████╗ ██████╗██╗ ██╗ - ██║ ██║██╔══██╗████╗ ████║██╔══██╗██╔══██╗██╔════╝██║ ██╔╝ - ███████║███████║██╔████╔██║██████╔╝███████║██║ █████╔╝ - ██╔══██║██╔══██║██║╚██╔╝██║██╔═══╝ ██╔══██║██║ ██╔═██╗ - ██║ ██║██║ ██║██║ ╚═╝ ██║██║ ██║ ██║╚██████╗██║ ██╗ - ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ - - ███████╗███████╗██████╗ ██╗ ██╗███████╗██████╗ - ██╔════╝██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗ - ███████╗█████╗ ██████╔╝██║ ██║█████╗ ██████╔╝ - ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██╔══╝ ██╔══██╗ - ███████║███████╗██║ ██║ ╚████╔╝ ███████╗██║ ██║ - ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝ - - - -EOF -} - -# Clear screen and show logo -clear -print_logo - -echo "Updating Arch..." -sudo pacman -Syu - -echo "Updating AUR..." - -if ! yay -Sua 2>/dev/null; then - echo "yay -Sua returned an error. Let's rebuild YAY." - sudo pacman -R yay - cd /tmp - git clone https://aur.archlinux.org/yay.git - cd yay - makepkg -si - cd .. - rm -rf yay - cd - yay -Sua --noconfirm -else - yay -Sua --noconfirm -fi - -# Updating the repo and installing... -echo "Updating HamPackServer..." - -REPO_DIR="$HOME/.local/share/HamPackServer" - -echo "Pulling latest HamPackServer repo..." -git -C "$REPO_DIR" pull - -echo "Running install.sh..." -bash "$REPO_DIR/install.sh" - -# Check whether the running kernel matches the installed modules — if not, a -# newer kernel was installed during this run and a reboot is required -if ! ls /usr/lib/modules/$(uname -r) > /dev/null 2>&1; then - echo "A newer kernel has been installed, a reboot is recommended." - read -rp "Reboot now? [y/N] " response - case "$response" in - [yY][eE][sS]|[yY]) - echo "Rebooting..." - sudo reboot - ;; - *) - echo "Reboot skipped. Please remember to reboot when convenient." - exit 0 - ;; - esac -else - echo "Kernel is up to date, no reboot needed. You may want to consider a reboot if other significant software was updated or installed." -fi diff --git a/install-compiled.sh b/install-compiled.sh index b6d767e..5b2e42b 100755 --- a/install-compiled.sh +++ b/install-compiled.sh @@ -3,7 +3,8 @@ set -e # # Purpose : Compile and install applications from compile.conf -CONF_FILE="$HOME/.local/share/HamPackServer/compile.conf" +HAMPACKSERVER_DIR="${HAMPACKSERVER_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}" +CONF_FILE="$HAMPACKSERVER_DIR/compile.conf" TMP_DIR="$HOME/.cache/hampack-build" VERSION_FILE="$HOME/.local/state/HamPackServer/.installed_versions" @@ -63,6 +64,19 @@ save_installed_version() { fi } +# Ask the user a yes/no question. Only install.sh asks; during `update` the +# answer is no, so `update` runs through without prompting +ask_yes_no() { + local question="$1" + + if [ -z "$HAMPACKSERVER_INTERACTIVE" ]; then + echo "$question [y/N] no (run \`sibling add\` again to be asked)" + return 1 + fi + read -rp "$question [y/N] " response > "$HOME/.bashrc" - echo '# HamPack: add user local bin to PATH' >> "$HOME/.bashrc" - echo 'export PATH="$HOME/.local/bin:$PATH" # LOCAL_BIN_PATH' >> "$HOME/.bashrc" -fi - -clear -print_logo - -cd ~ -sudo -v - -# Grant passwordless sudo for the duration of the install, revoke on exit -echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/99-hampack-install > /dev/null -sudo chmod 440 /etc/sudoers.d/99-hampack-install -trap "sudo rm -f /etc/sudoers.d/99-hampack-install" EXIT - -if ! command -v git &> /dev/null; then - echo "Installing git..." - sudo pacman -S --noconfirm git -fi - -if ! pacman -Qi base-devel &> /dev/null; then - echo "Installing base-devel..." - sudo pacman -S --noconfirm base-devel -else - echo "base-devel is already installed, skipping." -fi - -echo "Getting the latest version of HamPackServer..." -rm -rf ~/.local/share/HamPackServer -git clone https://gitea.young.computer/david/HamPackServer.git "$HOME/.local/share/HamPackServer" > /dev/null - -mkdir -p "$HOME/.local/bin" -cp "$HOME/.local/share/HamPackServer/hampackserverrefresh" "$HOME/.local/bin/hampackserverrefresh" -cp "$HOME/.local/share/HamPackServer/hampackserverupdate" "$HOME/.local/bin/hampackserverupdate" -cp "$HOME/.local/share/HamPackServer/hampackservercheck" "$HOME/.local/bin/hampackservercheck" - -mkdir -p "$HOME/.local/share/hamclock" -# Remove old user-level service if present -if [ -f "$HOME/.config/systemd/user/hamclock.service" ]; then - systemctl --user disable --now hamclock 2>/dev/null || true - rm "$HOME/.config/systemd/user/hamclock.service" - systemctl --user daemon-reload -fi -sed -e "s/__HAMCLOCK_USER__/$USER/g" -e "s|__HAMCLOCK_HOME__|$HOME|g" "$HOME/.local/share/HamPackServer/servicefiles/hamclock.service" | sudo tee /etc/systemd/system/hamclock.service > /dev/null -sudo systemctl daemon-reload -sudo systemctl enable hamclock -bash "$HOME/.local/share/HamPackServer/scripts/hamclock-cleanup.sh" - -cd ~/.local/share/HamPackServer - -echo "Updating system..." -sudo pacman -Syu --noconfirm - -install_yay() { - rm -rf /tmp/yay - git clone https://aur.archlinux.org/yay.git /tmp/yay - cd /tmp/yay - makepkg -si --noconfirm - cd ~/.local/share/HamPackServer - rm -rf /tmp/yay -} - -if ! command -v yay &> /dev/null; then - echo "Installing yay AUR helper..." - install_yay -else - echo "yay is already installed, skipping." -fi - -if ! yay --version &> /dev/null; then - echo "yay does not appear to be working, reinstalling..." - install_yay -fi - -# Source utility functions -source utils.sh - -# Source package list -if [ ! -f "packages.conf" ]; then - echo "Error: packages.conf not found!" - exit 1 -fi -source packages.conf - -echo "Installing servers..." -install_packages "${SERVERS[@]}" - -echo "Installing utilities..." -install_packages "${UTILITIES[@]}" - -if ! command -v pm2 &> /dev/null; then - npm install pm2 -g --prefix "$HOME/.local" -fi - -cd ~/.local/share/HamPackServer - -# Install Cockpit -if ! pacman -Qi cockpit &> /dev/null; then - echo "Installing Cockpit..." - sudo pacman -S --noconfirm cockpit - sudo systemctl enable --now cockpit.socket - echo "Cockpit installed. Access it at http://localhost:9090" -else - echo "Cockpit is already installed, skipping." -fi - -# Install Wavelog - -WAVELOG_DIR="$HOME/.local/bin/wavelog" - -if [ ! -d "$WAVELOG_DIR" ]; then echo "Installing Wavelog..." mkdir -p "$WAVELOG_DIR" - cp "$HOME/.local/share/HamPackServer/wavelog/docker-compose.yaml" "$WAVELOG_DIR/docker-compose.yaml" + cp "$SELF/wavelog/docker-compose.yaml" "$WAVELOG_DIR/docker-compose.yaml" WAVELOG_DB_PASS=$(openssl rand -base64 32 | tr -d '=/+' | cut -c1-24) sed -i "s|MARIADB_PASSWORD: wavelog # <- Insert a strong password here|MARIADB_PASSWORD: ${WAVELOG_DB_PASS}|" "$WAVELOG_DIR/docker-compose.yaml" @@ -157,14 +47,14 @@ if [ ! -d "$WAVELOG_DIR" ]; then fi echo "Waiting for Docker socket..." - timeout=30 + local timeout=30 while [ ! -S /var/run/docker.sock ] && [ $timeout -gt 0 ]; do sleep 1 timeout=$((timeout - 1)) done if [ ! -S /var/run/docker.sock ]; then echo "Error: Docker socket not available after 30 seconds." - exit 1 + return 1 fi sudo usermod -aG docker "$USER" @@ -172,37 +62,54 @@ if [ ! -d "$WAVELOG_DIR" ]; then sudo chmod 660 /var/run/docker.sock sg docker -c "docker compose -f '$WAVELOG_DIR/docker-compose.yaml' up -d" echo "Wavelog installed. Access it at http://localhost:8086" -else - echo "Wavelog is already installed, skipping." +} + +# --- Main --- + +set -e + +SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +COREDESKTOP="$HOME/.local/share/coredesktop" +LEGACY_DIR="$HOME/.local/share/HamPackServer" +SUDOERS_FILE=/etc/sudoers.d/99-hampack-install + +clear || true +print_logo + +if [ ! -d "$COREDESKTOP" ]; then + echo "HamPackServer requires CoreDesktop to be installed first." + echo "Please install CoreDesktop: https://coredesktop.federated.computer" + exit 1 fi -# Install openhamclock +# HamPackServer used to clone itself to ~/.local/share/HamPackServer. It now +# lives wherever `sibling` cloned it. +if [ -d "$LEGACY_DIR/.git" ] && [ "$LEGACY_DIR" != "$SELF" ]; then + echo "Removing the old HamPackServer install at $LEGACY_DIR..." + rm -rf "$LEGACY_DIR" +fi + +sudo -v + +# Grant passwordless sudo for the duration of the install, revoke on exit +echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee "$SUDOERS_FILE" > /dev/null +sudo chmod 440 "$SUDOERS_FILE" +trap 'sudo rm -f "$SUDOERS_FILE"' EXIT -echo "Installing openhamclock..." INSTALL_SUCCESS=true -if ! bash install-openhamclock.sh; then - echo "Warning: install-openhamclock.sh encountered errors. openhamclock may not have installed correctly." +# Let install-compiled.sh ask before building apps whose version it can't tell +if ! HAMPACKSERVER_INTERACTIVE=1 bash "$SELF/update.sh"; then INSTALL_SUCCESS=false fi -# Fix networking (Avahi mDNS) - -echo "Configuring networking..." - -if ! bash fix-networking.sh; then - echo "Warning: fix-networking.sh encountered errors. mDNS may not be configured correctly." +if ! install_wavelog; then + echo "Warning: Wavelog may not have installed correctly." INSTALL_SUCCESS=false fi -# Install Compiled Servers - -echo "Installing compiled servers..." - -if ! bash install-compiled.sh; then - echo "Warning: install-compiled.sh encountered errors. Some applications may not have installed correctly." - INSTALL_SUCCESS=false -fi +# Revoke passwordless sudo now, before a possible reboot skips the trap +sudo rm -f "$SUDOERS_FILE" echo "" if [ "$INSTALL_SUCCESS" = true ]; then @@ -227,21 +134,4 @@ case "$response" in ;; esac -# Check whether the running kernel matches the installed modules — if not, a -# newer kernel was installed during this run and a reboot is required -if ! ls /usr/lib/modules/$(uname -r) > /dev/null 2>&1; then - echo "A newer kernel has been installed, a reboot is recommended." - read -rp "Reboot now? [y/N] " response - case "$response" in - [yY][eE][sS]|[yY]) - echo "Rebooting..." - sudo reboot - ;; - *) - echo "Reboot skipped. Please remember to reboot when convenient." - exit 0 - ;; - esac -else - echo "Kernel is up to date, no reboot needed. You may want to consider a reboot if other significant software was updated or installed." -fi \ No newline at end of file +[ "$INSTALL_SUCCESS" = true ] diff --git a/scripts/hamclock-cleanup.sh b/scripts/hamclock-cleanup.sh index 30586bb..35b76df 100755 --- a/scripts/hamclock-cleanup.sh +++ b/scripts/hamclock-cleanup.sh @@ -14,6 +14,13 @@ HAMCLOCK_DATA_FILES=( ".hamclock" ) +# Nothing to do once the files have been migrated +migrate=false +for f in "${HAMCLOCK_DATA_FILES[@]}"; do + [ -f "$OLD_DIR/$f" ] && migrate=true +done +[ "$migrate" = true ] || exit 0 + echo "Stopping hamclock service..." sudo systemctl stop hamclock 2>/dev/null || true diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..0a37ceb --- /dev/null +++ b/update.sh @@ -0,0 +1,107 @@ +#!/bin/bash +# +# Purpose : Keep HamPackServer current (run by CoreDesktop's `update`, and by install.sh) + +SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +COREDESKTOP="$HOME/.local/share/coredesktop" +source "$COREDESKTOP/utils.sh" + +# Scripts and the check tool find files in this repo through $HAMPACKSERVER_DIR +export HAMPACKSERVER_DIR="$SELF" + +FAILED=() + +# Run one update step; a failure is reported but doesn't stop the later steps +step() { + local name="$1" + shift + echo "→ $name..." + if ! "$@"; then + echo "✗ $name failed." + FAILED+=("$name") + fi +} + +remove_stale_files() { + # Replaced by CoreDesktop's `update` and `sibling add` + rm -f "$HOME/.local/bin/hampackserverupdate" "$HOME/.local/bin/hampackserverrefresh" +} + +install_tools() { + mkdir -p "$HOME/.local/bin" + install_script "$SELF/hampackservercheck" "$HOME/.local/bin/hampackservercheck" +} + +install_hampackserver_packages() { + source "$SELF/packages.conf" + install_packages "${SERVERS[@]}" && install_packages "${UTILITIES[@]}" +} + +install_pm2() { + command -v pm2 &> /dev/null || npm install pm2 -g --prefix "$HOME/.local" +} + +enable_cockpit() { + if ! systemctl is-enabled cockpit.socket &> /dev/null; then + sudo systemctl enable --now cockpit.socket && + echo "Cockpit enabled. Access it at http://localhost:9090" + fi +} + +# Install the hamclock system service, restarting hamclock if the service or +# the binary changed +install_hamclock_service() { + local unit=/etc/systemd/system/hamclock.service + local rendered changed=false + + # Remove old user-level service if present + if [ -f "$HOME/.config/systemd/user/hamclock.service" ]; then + systemctl --user disable --now hamclock 2>/dev/null || true + rm "$HOME/.config/systemd/user/hamclock.service" + systemctl --user daemon-reload + fi + + mkdir -p "$HOME/.local/share/hamclock" + rendered=$(sed -e "s/__HAMCLOCK_USER__/$USER/g" -e "s|__HAMCLOCK_HOME__|$HOME|g" \ + "$SELF/servicefiles/hamclock.service") || return 1 + if [ "$rendered" != "$(cat "$unit" 2>/dev/null)" ]; then + echo "$rendered" | sudo tee "$unit" > /dev/null || return 1 + sudo systemctl daemon-reload || return 1 + changed=true + fi + enable_services hamclock || return 1 + + bash "$SELF/scripts/hamclock-cleanup.sh" || return 1 + + if [ "$changed" = true ] || [ "$(hamclock_mtime)" != "$HAMCLOCK_MTIME" ]; then + echo "Restarting hamclock..." + sudo systemctl restart hamclock + fi +} + +hamclock_mtime() { + stat -c %Y "$HOME/.local/bin/hamclock" 2>/dev/null +} + +# --- Main --- + +echo "Updating HamPackServer..." + +HAMCLOCK_MTIME=$(hamclock_mtime) + +step "Removing stale HamPackServer files" remove_stale_files +step "Installing HamPackServer tools" install_tools +step "Installing HamPackServer packages" install_hampackserver_packages +step "Installing pm2" install_pm2 +step "Enabling Cockpit" enable_cockpit +step "Configuring networking" bash "$SELF/fix-networking.sh" +step "Installing compiled servers" bash "$SELF/install-compiled.sh" +step "Installing hamclock service" install_hamclock_service +step "Installing openhamclock" bash "$SELF/install-openhamclock.sh" + +if (( ${#FAILED[@]} > 0 )); then + echo "HamPackServer updated, with errors in: ${FAILED[*]}" + exit 1 +fi + +echo "✓ HamPackServer updated."