View raw

1 #!/usr/bin/env bash 2 3 set -eEuo pipefail 4 5 readonly REPO_DIR="/opt/fapg/fapg-daq" 6 readonly NODE_BIN="${REPO_DIR}/roles/daq-node/bin/fapg-daq-node" 7 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 readonly SCRIPT_DIR 9 10 readonly SERVICE_NAME="fapg-daq-node.service" 11 readonly SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}" 12 13 readonly ENV_DIR="/etc/fapg-daq" 14 readonly ENV_FILE="${ENV_DIR}/daq.conf" 15 16 readonly STATE_DIR="/var/lib/fapg-daq" 17 readonly RUN_DIR="/run/fapg-daq" 18 19 readonly RUN_USER='fapg-daq' 20 readonly RUN_GROUP='fapg-daq' 21 22 readonly SERIAL_DEVICE='' 23 readonly READ_INTERVAL=5 24 readonly MQTT_HOST='fapg-daq-five-01' 25 readonly MQTT_PORT='1883' 26 readonly MQTT_USERNAME='fapg_zero' 27 MQTT_PASSWORD='' 28 29 function die() { 30 echo "ERROR: $*" >&2 31 exit 1 32 } 33 34 function require_root() { 35 if [[ "$(id -u)" -ne 0 ]]; then 36 die "$0 requires superuser privileges." 37 fi 38 } 39 40 function install_os_dependencies() { 41 apt-get update 42 apt-get install -y \ 43 perl \ 44 libnet-mqtt-simple-perl \ 45 libdevice-serialport-perl 46 47 echo "Installed all OS dependencies." 48 } 49 50 create_runtime_user() { 51 if ! getent group "${RUN_GROUP}" > /dev/null; then 52 addgroup --system "${RUN_GROUP}" 53 fi 54 55 if ! id "${RUN_USER}" > /dev/null 2>&1; then 56 adduser \ 57 --system \ 58 --ingroup "${RUN_GROUP}" \ 59 --home "${STATE_DIR}" \ 60 --no-create-home \ 61 --disabled-login \ 62 "${RUN_USER}" 63 fi 64 65 # USB serial devices are normally accessible to members of dialout. 66 usermod -aG dialout "${RUN_USER}" 67 68 echo "Created runtime user ${RUN_USER}, group ${RUN_GROUP}." 69 } 70 71 check_repo_layout() { 72 [[ -d "${REPO_DIR}" ]] || die "Repo not found at ${REPO_DIR}." 73 [[ -x "${NODE_BIN}" ]] || die "${NODE_BIN} does not exist or is not executable." 74 75 mkdir -p "${STATE_DIR}" "${RUN_DIR}" 76 chown "${RUN_USER}:${RUN_GROUP}" "${STATE_DIR}" "${RUN_DIR}" 77 78 echo "Verified layout of repo at ${REPO_DIR}." 79 } 80 81 function write_env_file() { 82 mkdir -p "${ENV_DIR}" 83 84 # TODO: print diff of existing and proposed env file 85 if [[ -f "${ENV_FILE}" ]]; then 86 echo "${ENV_FILE} already exists; leaving it unchanged." 87 chown root:"${RUN_GROUP}" "${ENV_FILE}" 88 chmod 0640 "${ENV_FILE}" 89 return 90 fi 91 92 if [[ -z "${MQTT_PASSWORD:-}" ]]; then 93 read -rsp "MQTT password for user '${MQTT_USERNAME}': " MQTT_PASSWORD 94 echo 95 fi 96 97 [[ -n "${MQTT_PASSWORD:-}" ]] || die "MQTT_PASSWORD is required." 98 99 # TODO: unsafe! 100 cat > "${ENV_FILE}" <<EOF 101 MQTT_SIMPLE_ALLOW_INSECURE_LOGIN=1 102 103 READ_INTERVAL=${READ_INTERVAL} 104 MQTT_HOST="${MQTT_HOST}" 105 MQTT_PORT="${MQTT_PORT}" 106 MQTT_USERNAME="${MQTT_USERNAME}" 107 MQTT_PASSWORD="${MQTT_PASSWORD}" 108 EOF 109 110 if [[ -n "${SERIAL_DEVICE}" ]]; then 111 echo "SERIAL_DEVICE=\"${SERIAL_DEVICE}\"" >> "${ENV_FILE}" 112 fi 113 114 chown root:"${RUN_GROUP}" "${ENV_FILE}" 115 chmod 0640 "${ENV_FILE}" 116 } 117 118 function write_systemd_service() { 119 install -m 0644 -o root -g root \ 120 "${SCRIPT_DIR}/etc/systemd/system/fapg-daq-node.service" \ 121 "${SERVICE_FILE}" 122 } 123 124 function enable_service() { 125 systemctl daemon-reload 126 systemctl enable "${SERVICE_NAME}" 127 systemctl restart "${SERVICE_NAME}" 128 } 129 130 show_status() { 131 cat <<"EOF" 132 Deployment complete. 133 Current service state: 134 EOF 135 systemctl --no-pager --full status "${SERVICE_NAME}" 136 } 137 138 function main() { 139 require_root 140 install_os_dependencies 141 # install_perl_dependencies 142 create_runtime_user 143 check_repo_layout 144 write_env_file 145 write_systemd_service 146 enable_service 147 show_status 148 } 149 150 main "$@" 151