Repository navigation
Expand file tree
/
Copy pathautostream_uninstall.sh
More file actions
291 lines (256 loc) · 10.8 KB
/
Copy pathautostream_uninstall.sh
File metadata and controls
291 lines (256 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/usr/bin/env bash
#
# autostream_uninstall.sh
#
# Quick-and-dirty uninstaller for autostream on Raspberry Pi OS.
# This removes the main autostream installation and attempts to remove
# OwnTone, but intentionally does not try to reverse every shared system
# change made by the installer.
set -u
set -o pipefail
SCRIPT_NAME="$(basename "$0")"
info() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*"; }
error() { echo "[ERROR] $*"; }
# Bluetooth input subsystem removal (installer/lib/bluetooth.sh). Sourced
# from the checkout the uninstaller is run from -- if this is a standalone
# copy without that library, removal just falls back to leaving the
# Bluetooth-specific files/units in place (they are also covered
# individually below where identifiable). The subsystem is always present
# (installed unconditionally, disabled), so removal is always attempted.
INSTALLER_LIB_DIR="$(cd "$(dirname "$0")/installer/lib" 2>/dev/null && pwd || true)"
if [[ -n "${INSTALLER_LIB_DIR}" && -f "${INSTALLER_LIB_DIR}/hardware.sh" && -f "${INSTALLER_LIB_DIR}/bluetooth.sh" ]]; then
# shellcheck source=installer/lib/hardware.sh
source "${INSTALLER_LIB_DIR}/hardware.sh"
# shellcheck source=installer/lib/bluetooth.sh
source "${INSTALLER_LIB_DIR}/bluetooth.sh"
fi
# remove_bluetooth_if_enabled: call remove_bluetooth_stack (disable/remove
# the unit, module config, bluez fragment). Apt packages are kept, matching
# this uninstaller's existing light-touch stance. Must run before
# /var/lib/autostream is removed below.
remove_bluetooth_if_enabled() {
if ! command -v remove_bluetooth_stack >/dev/null 2>&1; then
warn "installer/lib/bluetooth.sh is unavailable; the Bluetooth unit/module"
warn "config/bluez fragment will need to be removed manually."
return 0
fi
info "Removing Bluetooth input subsystem"
remove_bluetooth_stack
}
require_sudo() {
if [[ ${EUID} -ne 0 ]]; then
error "This script must be run as root (e.g. sudo ./${SCRIPT_NAME})."
exit 1
fi
}
has_tty() {
[[ -r /dev/tty && -w /dev/tty ]]
}
prompt_continue() {
cat <<'EOF'
=============================================================================
AUTOSTREAM UNINSTALLER
=============================================================================
This script uninstalls autostream and OwnTone, but it is intentionally
incomplete. It will leave some fragments and shared system components behind.
It does NOT try to undo every change to shared system files.
Use this only if you understand that some cleanup may still need to be done
manually afterward.
=============================================================================
EOF
if has_tty; then
local ans
read -r -p "Continue with uninstall? (Y/N) " ans < /dev/tty || true
case "${ans:-N}" in
Y|y) ;;
*) error "Aborted by user."; exit 1 ;;
esac
else
error "Interactive confirmation requires a TTY."
exit 1
fi
}
stop_and_disable_service() {
local svc="$1"
if systemctl list-unit-files "${svc}" >/dev/null 2>&1; then
info "Stopping ${svc}"
systemctl stop "${svc}" >/dev/null 2>&1 || warn "Could not stop ${svc}"
info "Disabling ${svc}"
systemctl disable "${svc}" >/dev/null 2>&1 || warn "Could not disable ${svc}"
else
info "Service ${svc} not present; skipping"
fi
}
remove_path() {
local path="$1"
if [[ -e "${path}" || -L "${path}" ]]; then
info "Removing ${path}"
rm -rf "${path}" || warn "Failed to remove ${path}"
else
info "Path ${path} not present; skipping"
fi
}
apt_remove_owntone() {
if command -v apt-get >/dev/null 2>&1; then
info "Attempting to remove packaged OwnTone"
DEBIAN_FRONTEND=noninteractive apt-get remove -y owntone >/dev/null 2>&1 \
|| warn "apt remove owntone failed or owntone was not installed as a package"
else
warn "apt-get not found; skipping packaged OwnTone removal"
fi
}
restore_wifi_profiles() {
# The wifi watcher (see migrate_client_profiles_autoconnect_no in
# platform/wifi_config.py) sets connection.autoconnect no on every Wi-Fi
# client profile and is the sole reconnection agent while autostream is
# installed; a surviving profile may also carry an 802-11-wireless.bssid
# pin and a connection.interface-name restriction. Once autostream is
# uninstalled nothing re-enables those profiles, so hand Wi-Fi back to
# stock NetworkManager behaviour here. This is best-effort: a missing
# nmcli, a stopped NetworkManager, or a single profile failure must not
# abort the uninstall.
if ! command -v nmcli >/dev/null 2>&1; then
info "nmcli not found; skipping Wi-Fi profile restoration"
return 0
fi
info "Restoring Wi-Fi connection profiles to NetworkManager defaults"
local line uuid type mode
while IFS=: read -r uuid type; do
[[ "${type}" == "802-11-wireless" ]] || continue
mode="$(nmcli -g 802-11-wireless.mode connection show "${uuid}" 2>/dev/null || true)"
if [[ "${mode}" == "ap" ]]; then
if nmcli connection delete "${uuid}" >/dev/null 2>&1; then
info "Deleted leftover AP profile ${uuid}"
else
warn "Failed to delete AP profile ${uuid}"
fi
else
if nmcli connection modify "${uuid}" \
connection.autoconnect yes \
802-11-wireless.bssid "" \
connection.interface-name "" >/dev/null 2>&1; then
info "Restored autoconnect and cleared pins on Wi-Fi profile ${uuid}"
else
warn "Failed to restore Wi-Fi profile ${uuid}"
fi
fi
done < <(nmcli -t -f UUID,TYPE connection show 2>/dev/null || true)
}
prompt_reboot() {
if ! has_tty; then
info "Please reboot the device when convenient."
return 0
fi
local ans
echo
read -r -p "Reboot now? (Y/N) " ans < /dev/tty || true
case "${ans:-N}" in
Y|y)
info "Rebooting..."
reboot
;;
*)
info "Reboot skipped. A reboot is recommended."
;;
esac
}
main() {
require_sudo
prompt_continue
info "Stopping services"
stop_and_disable_service autostream_update_retry.service
stop_and_disable_service autostream_updater.timer
stop_and_disable_service autostream_updater.service
stop_and_disable_service autostream.service
stop_and_disable_service autostream_monitor.service
stop_and_disable_service autostream_wifi_watcher.service
stop_and_disable_service autostream_storage_guard.timer
stop_and_disable_service autostream_storage_guard.service
stop_and_disable_service autostream_log_policy.timer
stop_and_disable_service autostream_log_policy.service
stop_and_disable_service autostream_sdcardhealth.timer
stop_and_disable_service autostream_sdcardhealth.service
stop_and_disable_service autostream_sdcardhealth_boot.service
stop_and_disable_service autostream_dnsmasq.service
stop_and_disable_service autostream_bluetooth.service
stop_and_disable_service owntone.service
stop_and_disable_service nginx.service
restore_wifi_profiles
remove_bluetooth_if_enabled
info "Removing autostream application files"
remove_path /opt/autostream
remove_path /etc/autostream
remove_path /var/log/autostream
remove_path /var/lib/autostream
remove_path /usr/local/libexec/autostream
apt_remove_owntone
info "Removing possible OwnTone Mini files"
remove_path /usr/sbin/owntone
remove_path /etc/systemd/system/owntone.service
remove_path /etc/systemd/system/owntone.service.d
remove_path /etc/owntone-settings.json
remove_path /etc/owntone.conf
remove_path /etc/apt/sources.list.d/owntone.list
remove_path /usr/share/keyrings/owntone-archive-keyring.gpg
info "Removing autostream nginx configuration"
remove_path /etc/nginx/sites-enabled/autostream-nginx.conf
remove_path /etc/nginx/sites-available/autostream-nginx.conf
remove_path /etc/nginx/conf.d/autostream-nginxd.conf
remove_path /etc/nginx/conf.d/99-autostream-access-log.conf
info "Removing autostream systemd units"
remove_path /etc/systemd/system/autostream_update_retry.service
remove_path /etc/systemd/system/autostream_updater.service
remove_path /etc/systemd/system/autostream_updater.timer
remove_path /etc/systemd/system/autostream.service
remove_path /etc/systemd/system/autostream_monitor.service
remove_path /etc/systemd/system/autostream_wifi_watcher.service
remove_path /etc/systemd/system/autostream_dnsmasq.service
remove_path /etc/systemd/system/autostream_sdcardhealth.service
remove_path /etc/systemd/system/autostream_sdcardhealth.timer
remove_path /etc/systemd/system/autostream_sdcardhealth_boot.service
remove_path /etc/systemd/system/autostream_storage_guard.service
remove_path /etc/systemd/system/autostream_storage_guard.timer
remove_path /etc/systemd/system/autostream_log_policy.service
remove_path /etc/systemd/system/autostream_log_policy.timer
remove_path /etc/systemd/system/autostream_bluetooth.service
info "Removing autostream sudoers snippets"
remove_path /etc/sudoers.d/autostream_updater
remove_path /etc/sudoers.d/autostream_admin
info "Removing other autostream-managed files we can identify confidently"
remove_path /usr/local/libexec/autostream/autostream_sdcardhealth
remove_path /var/lib/autostream/sdcardhealth-status.json
remove_path /var/lib/autostream/sdcardhealth.json
remove_path /var/lib/autostream/sdcardhealth.inflight
remove_path /usr/local/sbin/sdmon
remove_path /usr/lib/tmpfiles.d/autostream.conf
remove_path /run/autostream-pipes
remove_path /etc/avahi/services/autostream.service
remove_path /etc/logrotate.d/autostream
remove_path /etc/dnsmasq.d/autostream-setup.conf
remove_path /etc/autostream-network.json
remove_path /boot/firmware/pin.txt
remove_path /boot/pin.txt
remove_path /usr/local/share/autostream/dnsmasq/autostream-setup.conf
remove_path /run/autostream/autostream-setup.conf
remove_path /etc/NetworkManager/dispatcher.d/99-wlan-fix
remove_path /etc/NetworkManager/conf.d/mdns.conf
remove_path /etc/NetworkManager/conf.d/wifi-powersave.conf
remove_path /etc/systemd/journald.conf.d/99-autostream-storage.conf
remove_path /etc/systemd/journald.conf.d/zz-autostream-diag-persistent.conf
remove_path /var/lib/autostream/journald-persistent.applied
systemctl restart systemd-journald || warn "systemctl restart systemd-journald failed"
remove_path /etc/systemd/logind.conf.d/90-autostream-ignore-power-key.conf
systemctl restart systemd-logind || warn "systemctl restart systemd-logind failed"
# Bluetooth input subsystem leftovers, as a fallback in case
# remove_bluetooth_if_enabled (above) could not source installer/lib/bluetooth.sh.
# Idempotent no-ops if remove_bluetooth_stack already removed them.
remove_path /etc/modules-load.d/autostream-bluetooth.conf
remove_path /etc/modprobe.d/autostream-bluetooth.conf
remove_path /etc/bluetooth/main.conf.d/autostream.conf
info "Reloading systemd manager configuration"
systemctl daemon-reload || warn "systemctl daemon-reload failed"
info "Uninstall complete. Some fragments may still remain."
prompt_reboot
}
main "$@"