[Perl] DAQ system for the FAPG.
Ensure idempotency of deployment scripts.
Changed files
roles/daq-hub/deploy
@@ -2,44 +2,73 @@
2
2
3
3
set -eEuo pipefail
4
4
5
Removed:
if [[ "${EUID}" -ne 0 ]]; then
6
Removed:
echo "error: run as root, e.g. sudo $0" >&2
5
Added:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
Added:
readonly SCRIPT_DIR
7
Added:
readonly PASSWD_FILE="/etc/mosquitto/passwd"
8
Added:
readonly SERVICE_NAME="mosquitto.service"
9
Added:
10
Added:
function die() {
11
Added:
echo "ERROR: $*" >&2
7
12
exit 1
8
Removed:
fi
13
Added:
}
9
14
10
Removed:
os_dependencies="mosquitto mosquitto-clients"
11
Removed:
apt update && apt install -y ${os_dependencies}
15
Added:
function require_root() {
16
Added:
if [[ "${EUID}" -ne 0 ]]; then
17
Added:
die "run as root, e.g. sudo $0"
18
Added:
fi
19
Added:
}
12
20
21
Added:
function passwd_has_user() {
22
Added:
local user="$1"
23
Added:
24
Added:
[[ -f "${PASSWD_FILE}" ]] || return 1
25
Added:
grep -qE "^${user}:" "${PASSWD_FILE}"
26
Added:
}
27
Added:
28
Added:
function ensure_mosquitto_password() {
29
Added:
local user="$1"
30
Added:
31
Added:
if passwd_has_user "${user}"; then
32
Added:
echo "Mosquitto password for ${user} already exists; leaving it unchanged."
33
Added:
return
34
Added:
fi
35
Added:
36
Added:
echo "Enter password for ${user}"
37
Added:
if [[ -f "${PASSWD_FILE}" ]]; then
38
Added:
mosquitto_passwd "${PASSWD_FILE}" "${user}"
39
Added:
else
40
Added:
mosquitto_passwd -c "${PASSWD_FILE}" "${user}"
41
Added:
fi
42
Added:
}
43
Added:
44
Added:
require_root
45
Added:
46
Added:
os_dependencies=(mosquitto mosquitto-clients)
47
Added:
apt update && apt install -y "${os_dependencies[@]}"
48
Added:
13
49
# Install files
14
50
15
51
install -d -m 0755 -o root -g root /etc/mosquitto/conf.d
16
52
17
53
install -m 0640 -o root -g mosquitto \
18
Removed:
./etc/mosquitto/acl \
54
Added:
"${SCRIPT_DIR}/etc/mosquitto/acl" \
19
55
/etc/mosquitto/acl
20
56
21
57
install -m 0644 -o root -g root \
22
Removed:
./etc/mosquitto/conf.d/fapg-home.conf \
58
Added:
"${SCRIPT_DIR}/etc/mosquitto/conf.d/fapg-home.conf" \
23
59
/etc/mosquitto/conf.d/fapg-home.conf
24
60
25
61
# Password management
26
62
27
Removed:
echo "Enter password for fapg_zero"
28
Removed:
if [[ ! -f /etc/mosquitto/passwd ]]; then
29
Removed:
mosquitto_passwd -c /etc/mosquitto/passwd fapg_zero
30
Removed:
else
31
Removed:
mosquitto_passwd /etc/mosquitto/passwd fapg_zero
32
Removed:
fi
63
Added:
ensure_mosquitto_password fapg_zero
64
Added:
ensure_mosquitto_password fapg_vps
33
65
34
Removed:
echo "Enter password for fapg_vps"
35
Removed:
mosquitto_passwd /etc/mosquitto/passwd fapg_vps
66
Added:
chown root:mosquitto "${PASSWD_FILE}"
67
Added:
chmod 0640 "${PASSWD_FILE}"
36
68
37
Removed:
chown root:mosquitto /etc/mosquitto/passwd
38
Removed:
chmod 0640 /etc/mosquitto/passwd
39
Removed:
40
69
# System service activation
41
70
42
Removed:
systemctl enable mosquitto
43
Removed:
systemctl restart mosquitto
71
Added:
systemctl enable "${SERVICE_NAME}"
72
Added:
systemctl restart "${SERVICE_NAME}"
44
73
45
Removed:
systemctl --no-pager --full status mosquitto
74
Added:
systemctl --no-pager --full status "${SERVICE_NAME}"
roles/daq-node/deploy
@@ -4,6 +4,8 @@
4
4
5
5
readonly REPO_DIR="/opt/fapg/fapg-daq"
6
6
readonly NODE_BIN="${REPO_DIR}/roles/daq-node/bin/fapg-daq-node"
7
Added:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
Added:
readonly SCRIPT_DIR
7
9
8
10
readonly SERVICE_NAME="fapg-daq-node.service"
9
11
readonly SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}"
@@ -36,6 +38,7 @@
36
38
}
37
39
38
40
function install_os_dependencies() {
41
Added:
apt-get update
39
42
apt-get install -y \
40
43
perl \
41
44
libnet-mqtt-simple-perl \
@@ -80,7 +83,9 @@
80
83
81
84
# TODO: print diff of existing and proposed env file
82
85
if [[ -f "${ENV_FILE}" ]]; then
83
Removed:
echo "${ENV_FILE} already exists, remove or edit manually if necessary."
86
Added:
echo "${ENV_FILE} already exists; leaving it unchanged."
87
Added:
chown root:"${RUN_GROUP}" "${ENV_FILE}"
88
Added:
chmod 0640 "${ENV_FILE}"
84
89
return
85
90
fi
86
91
@@ -111,13 +116,15 @@
111
116
}
112
117
113
118
function write_systemd_service() {
114
Removed:
cat etc/systemd/system/fapg-daq-node.service > "${SERVICE_FILE}"
115
Removed:
chmod 0644 "${SERVICE_FILE}"
119
Added:
install -m 0644 -o root -g root \
120
Added:
"${SCRIPT_DIR}/etc/systemd/system/fapg-daq-node.service" \
121
Added:
"${SERVICE_FILE}"
116
122
}
117
123
118
124
function enable_service() {
119
125
systemctl daemon-reload
120
Removed:
systemctl enable --now "${SERVICE_NAME}"
126
Added:
systemctl enable "${SERVICE_NAME}"
127
Added:
systemctl restart "${SERVICE_NAME}"
121
128
}
122
129
123
130
show_status() {
roles/daq-recorder/deploy
@@ -1,14 +1,135 @@
1
1
#!/usr/bin/env bash
2
2
3
Removed:
sudo apt install \
4
Removed:
sqlite3 \
5
Removed:
libdbi-perl \
6
Removed:
libdbd-sqlite3-perl \
7
Removed:
libnet-mqtt-simple-perl
3
Added:
set -eEuo pipefail
8
4
9
Removed:
sudo useradd \
10
Removed:
--system \
11
Removed:
--home-dir /var/lib/fapg-daq \
12
Removed:
--create-home \
13
Removed:
--shell /usr/sbin/nologin \
14
Removed:
fapg-daq
5
Added:
readonly REPO_DIR="/opt/fapg/fapg-daq"
6
Added:
readonly RECORDER_BIN="${REPO_DIR}/roles/daq-recorder/bin/fapg-daq-mqtt-sqlite"
7
Added:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
Added:
readonly SCRIPT_DIR
9
Added:
10
Added:
readonly SERVICE_NAME="fapg-daq-mqtt-sqlite.service"
11
Added:
readonly SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}"
12
Added:
13
Added:
readonly ENV_DIR="/etc/fapg-daq"
14
Added:
readonly ENV_FILE="${ENV_DIR}/mqtt-sqlite.env"
15
Added:
16
Added:
readonly STATE_DIR="/var/lib/fapg-daq"
17
Added:
readonly RUN_USER="fapg-daq"
18
Added:
readonly RUN_GROUP="fapg-daq"
19
Added:
20
Added:
readonly MQTT_HOST="10.77.0.2"
21
Added:
readonly MQTT_PORT="1883"
22
Added:
readonly MQTT_USERNAME="fapg_vps"
23
Added:
readonly MQTT_TOPIC="fapg/daq/#"
24
Added:
MQTT_PASSWORD=""
25
Added:
26
Added:
function die() {
27
Added:
echo "ERROR: $*" >&2
28
Added:
exit 1
29
Added:
}
30
Added:
31
Added:
function require_root() {
32
Added:
if [[ "$(id -u)" -ne 0 ]]; then
33
Added:
die "$0 requires superuser privileges."
34
Added:
fi
35
Added:
}
36
Added:
37
Added:
function install_os_dependencies() {
38
Added:
apt-get update
39
Added:
apt-get install -y \
40
Added:
perl \
41
Added:
sqlite3 \
42
Added:
libdbi-perl \
43
Added:
libdbd-sqlite3-perl \
44
Added:
libnet-mqtt-simple-perl
45
Added:
}
46
Added:
47
Added:
function create_runtime_user() {
48
Added:
if ! getent group "${RUN_GROUP}" > /dev/null; then
49
Added:
addgroup --system "${RUN_GROUP}"
50
Added:
fi
51
Added:
52
Added:
if ! id "${RUN_USER}" > /dev/null 2>&1; then
53
Added:
adduser \
54
Added:
--system \
55
Added:
--ingroup "${RUN_GROUP}" \
56
Added:
--home "${STATE_DIR}" \
57
Added:
--no-create-home \
58
Added:
--disabled-login \
59
Added:
"${RUN_USER}"
60
Added:
fi
61
Added:
62
Added:
mkdir -p "${STATE_DIR}"
63
Added:
chown "${RUN_USER}:${RUN_GROUP}" "${STATE_DIR}"
64
Added:
}
65
Added:
66
Added:
function check_repo_layout() {
67
Added:
[[ -d "${REPO_DIR}" ]] || die "Repo not found at ${REPO_DIR}."
68
Added:
[[ -x "${RECORDER_BIN}" ]] || die "${RECORDER_BIN} does not exist or is not executable."
69
Added:
}
70
Added:
71
Added:
function write_env_file() {
72
Added:
mkdir -p "${ENV_DIR}"
73
Added:
74
Added:
if [[ -f "${ENV_FILE}" ]]; then
75
Added:
echo "${ENV_FILE} already exists; leaving it unchanged."
76
Added:
chown root:"${RUN_GROUP}" "${ENV_FILE}"
77
Added:
chmod 0640 "${ENV_FILE}"
78
Added:
return
79
Added:
fi
80
Added:
81
Added:
if [[ -z "${MQTT_PASSWORD:-}" ]]; then
82
Added:
read -rsp "MQTT password for user '${MQTT_USERNAME}': " MQTT_PASSWORD
83
Added:
echo
84
Added:
fi
85
Added:
86
Added:
[[ -n "${MQTT_PASSWORD:-}" ]] || die "MQTT_PASSWORD is required."
87
Added:
88
Added:
cat > "${ENV_FILE}" <<EOF
89
Added:
MQTT_SIMPLE_ALLOW_INSECURE_LOGIN=1
90
Added:
91
Added:
MQTT_HOST=${MQTT_HOST}
92
Added:
MQTT_PORT=${MQTT_PORT}
93
Added:
MQTT_USERNAME=${MQTT_USERNAME}
94
Added:
MQTT_PASSWORD=${MQTT_PASSWORD}
95
Added:
MQTT_TOPIC=${MQTT_TOPIC}
96
Added:
97
Added:
FAPG_DAQ_DB=${STATE_DIR}/readings.sqlite3
98
Added:
EOF
99
Added:
100
Added:
chown root:"${RUN_GROUP}" "${ENV_FILE}"
101
Added:
chmod 0640 "${ENV_FILE}"
102
Added:
}
103
Added:
104
Added:
function write_systemd_service() {
105
Added:
install -m 0644 -o root -g root \
106
Added:
"${SCRIPT_DIR}/etc/systemd/system/fapg-daq-mqtt-sqlite.service" \
107
Added:
"${SERVICE_FILE}"
108
Added:
}
109
Added:
110
Added:
function enable_service() {
111
Added:
systemctl daemon-reload
112
Added:
systemctl enable "${SERVICE_NAME}"
113
Added:
systemctl restart "${SERVICE_NAME}"
114
Added:
}
115
Added:
116
Added:
function show_status() {
117
Added:
cat <<"EOF"
118
Added:
Deployment complete.
119
Added:
Current service state:
120
Added:
EOF
121
Added:
systemctl --no-pager --full status "${SERVICE_NAME}"
122
Added:
}
123
Added:
124
Added:
function main() {
125
Added:
require_root
126
Added:
install_os_dependencies
127
Added:
create_runtime_user
128
Added:
check_repo_layout
129
Added:
write_env_file
130
Added:
write_systemd_service
131
Added:
enable_service
132
Added:
show_status
133
Added:
}
134
Added:
135
Added:
main "$@"
roles/dashboard/deploy
@@ -0,0 +1,91 @@
1
Added:
#!/usr/bin/env bash
2
Added:
3
Added:
set -eEuo pipefail
4
Added:
5
Added:
readonly REPO_DIR="/opt/fapg/fapg-daq"
6
Added:
readonly DASHBOARD_SCRIPT="${REPO_DIR}/roles/dashboard/script/dashboard"
7
Added:
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
Added:
readonly SCRIPT_DIR
9
Added:
10
Added:
readonly SERVICE_NAME="fapg-daq-dashboard.service"
11
Added:
readonly SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}"
12
Added:
13
Added:
readonly STATE_DIR="/var/lib/fapg-daq"
14
Added:
readonly RUN_USER="fapg-daq"
15
Added:
readonly RUN_GROUP="fapg-daq"
16
Added:
17
Added:
function die() {
18
Added:
echo "ERROR: $*" >&2
19
Added:
exit 1
20
Added:
}
21
Added:
22
Added:
function require_root() {
23
Added:
if [[ "$(id -u)" -ne 0 ]]; then
24
Added:
die "$0 requires superuser privileges."
25
Added:
fi
26
Added:
}
27
Added:
28
Added:
function install_os_dependencies() {
29
Added:
apt-get update
30
Added:
apt-get install -y \
31
Added:
perl \
32
Added:
libdbd-sqlite3-perl \
33
Added:
libmojolicious-perl \
34
Added:
libmojo-sqlite-perl
35
Added:
}
36
Added:
37
Added:
function create_runtime_user() {
38
Added:
if ! getent group "${RUN_GROUP}" > /dev/null; then
39
Added:
addgroup --system "${RUN_GROUP}"
40
Added:
fi
41
Added:
42
Added:
if ! id "${RUN_USER}" > /dev/null 2>&1; then
43
Added:
adduser \
44
Added:
--system \
45
Added:
--ingroup "${RUN_GROUP}" \
46
Added:
--home "${STATE_DIR}" \
47
Added:
--no-create-home \
48
Added:
--disabled-login \
49
Added:
"${RUN_USER}"
50
Added:
fi
51
Added:
52
Added:
mkdir -p "${STATE_DIR}"
53
Added:
chown "${RUN_USER}:${RUN_GROUP}" "${STATE_DIR}"
54
Added:
}
55
Added:
56
Added:
function check_repo_layout() {
57
Added:
[[ -d "${REPO_DIR}" ]] || die "Repo not found at ${REPO_DIR}."
58
Added:
[[ -f "${DASHBOARD_SCRIPT}" ]] || die "${DASHBOARD_SCRIPT} does not exist."
59
Added:
}
60
Added:
61
Added:
function write_systemd_service() {
62
Added:
install -m 0644 -o root -g root \
63
Added:
"${SCRIPT_DIR}/etc/systemd/system/fapg-daq-dashboard.service" \
64
Added:
"${SERVICE_FILE}"
65
Added:
}
66
Added:
67
Added:
function enable_service() {
68
Added:
systemctl daemon-reload
69
Added:
systemctl enable "${SERVICE_NAME}"
70
Added:
systemctl restart "${SERVICE_NAME}"
71
Added:
}
72
Added:
73
Added:
function show_status() {
74
Added:
cat <<"EOF"
75
Added:
Deployment complete.
76
Added:
Current service state:
77
Added:
EOF
78
Added:
systemctl --no-pager --full status "${SERVICE_NAME}"
79
Added:
}
80
Added:
81
Added:
function main() {
82
Added:
require_root
83
Added:
install_os_dependencies
84
Added:
create_runtime_user
85
Added:
check_repo_layout
86
Added:
write_systemd_service
87
Added:
enable_service
88
Added:
show_status
89
Added:
}
90
Added:
91
Added:
main "$@"