Ensure idempotency of deployment scripts.

Commit
c1b093d17564d8cce6bf7fc3938de6df6124e263
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
roles/daq-hub/deploy
index f5f7d468..33dca951 100755..100755
@@ -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
index c5a25a2c..d3543711 100755..100755
@@ -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
index 6240692b..a048c1b7 100755..100755
@@ -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
index 00000000..dbef9e8e 000000..100755
@@ -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 "$@"