#!/bin/bash # Install the eco status server as a *user* systemd service on this host. # # User-level (`systemctl --user`) rather than system-level on purpose: it # needs no root, and the service then runs as the invoking account - which # matters twice for this server. It writes status.json into the pgroup's # res/ tree, so it needs that account's pgroup membership; and several # bernina components authenticate to auxiliary machines over SSH during # __init__, so it needs that account's SSH credentials. # # The unit just calls `eco-status-server start` in the foreground, so the # interactive command and the service run exactly the same thing. set -euo pipefail SELF_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)" LAUNCHER="${ECO_STATUS_SERVER_LAUNCHER:-$SELF_DIR/eco-status-server}" UNIT_DIR="$HOME/.config/systemd/user" UNIT="$UNIT_DIR/eco-status-server.service" ENV_FILE="${ECO_STATUS_SERVER_ENV:-$HOME/.config/eco-status-server.env}" usage() { cat <&2; usage; exit 2 ;; esac done [ -x "$LAUNCHER" ] || { echo "launcher not executable: $LAUNCHER" >&2; exit 1; } mkdir -p "$UNIT_DIR" "$(dirname "$ENV_FILE")" if [ ! -e "$ENV_FILE" ]; then { echo "# Environment for the eco status server (systemd EnvironmentFile" echo "# syntax: KEY=value, no export, no shell expansion). Edit to taste." echo "ECO_STATUS_SERVER_CHECKOUT=${ECO_STATUS_SERVER_CHECKOUT:-/sf/bernina/code/gac-bernina/eco}" echo "ECO_STATUS_SERVER_CONFIG=${ECO_STATUS_SERVER_CONFIG:-/sf/bernina/config/eco_status_server/bernina_namespace.json}" echo "ECO_STATUS_SERVER_PYTHON=${ECO_STATUS_SERVER_PYTHON:-/sf/bernina/applications/python/.pixi/envs/bpy312/bin/python}" echo echo "# Channel Access settings, captured from the shell that ran the" echo "# installer. A systemd user service inherits almost nothing, and" echo "# without EPICS_CA_ADDR_LIST the server talks to the local" echo "# broadcast domain instead of the beamline gateway: measured on" echo "# saresb-cons-04, that is the difference between 77 of 87" echo "# components initializing and 49 of 87." env | grep '^EPICS_' | sort || true } > "$ENV_FILE" echo "wrote template $ENV_FILE - check it before starting the service" if ! grep -q '^EPICS_CA_ADDR_LIST=' "$ENV_FILE"; then echo echo "WARNING: EPICS_CA_ADDR_LIST was not set in this shell, so it is" >&2 echo " not in $ENV_FILE either. Re-run this from a shell where" >&2 echo " Channel Access works, or add it by hand - otherwise the" >&2 echo " service will start but most components will not connect." >&2 fi else echo "keeping existing $ENV_FILE" fi if [ -e "$UNIT" ] && [ "$FORCE" -eq 0 ]; then echo "$UNIT already exists; re-run with --force to overwrite" >&2 exit 1 fi cat > "$UNIT" < dumps every thread's stack into the journal - # the way to see which component a stuck initialization is sitting in. EOF