Opennet Firmware
modules.sh
gehe zur Dokumentation dieser Datei
1## @defgroup modules Module
2## @brief Verwaltung der Opennet-Module für verschiedene Funktionen/Rollen
3# Beginn der Doku-Gruppe
4## @{
5
6# Basis-URL für Opennet-Paketinstallationen
7ON_OPKG_REPOSITORY_URL_PREFIX="https://downloads.opennet-initiative.de/openwrt"
8# temporäre Datei für Installation von Opennet-Paketen
9ON_OPKG_CONF_PATH="${IPKG_INSTROOT:-}/tmp/opkg-opennet.conf"
10# shellcheck disable=SC2034
11DEFAULT_MODULES_ENABLED="on-olsr2"
12
14# Erzeuge die uci-Sektion "on-core.modules" und aktiviere Standard-Module.
15_prepare_on_modules() {
16 [ -n "$(uci_get "on-core.modules")" ] && return
17 uci set "on-core.modules=modules"
18}
19
20
21## @fn is_on_module_installed_and_enabled()
22## @brief Pruefe ob ein Opennet-Modul sowohl installiert, als auch aktiviert ist.
23## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
24## @details Die Aktivierung eines Modules wird anhand der uci-Einstellung "${module}.settings.enabled" geprueft.
25## Der Standardwert ist "false" (ausgeschaltet).
27 trap 'error_trap is_on_module_installed_and_enabled "$*"' EXIT
28 local module="$1"
29 _prepare_on_modules
30 is_on_module_installed "$module" && _is_on_module_enabled "$module" && return 0
31 trap "" EXIT && return 1
32}
33
34
35_is_on_module_enabled() {
36 local module="$1"
37 _prepare_on_modules
38 uci_is_in_list "on-core.modules.enabled" "$module" && return 0
39 trap "" EXIT && return 1
40}
41
42
43## @fn is_on_module_installed()
44## @brief Pruefe ob ein Opennet-Modul installiert ist.
45## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
47 local module="$1"
48 _prepare_on_modules
49 is_package_installed "$module" && return 0
50 trap "" EXIT && return 1
51}
52
53
54## @fn enable_on_module()
55## @brief Aktiviere ein Opennet-Modul
56## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
58 trap 'error_trap enable_on_module "$*"' EXIT
59 local module="$1"
60 _prepare_on_modules
63 uci_add_list "on-core.modules.enabled" "$module"
64 apply_changes "on-core" "$module"
65}
66
68## @fn disable_on_module()
69## @brief Deaktiviere ein Opennet-Modul
70## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
72 trap 'error_trap disable_on_module "$*"' EXIT
73 local module="$1"
75 _is_on_module_enabled "$module" || return 0
76 uci_delete_list "on-core.modules.enabled" "$module"
77 apply_changes "on-core" "$module"
78}
79
80
81## @fn warn_if_unknown_module()
82## @brief Gib eine Warnung aus, falls der angegebene Modul-Name unbekannt ist.
83## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
84## @details Das Ergebnis der Prüfung ist nur für Warnmeldungen geeignet, da es im Laufe der Zeit
85## Veränderungen in der Liste der bekannten Module geben kann.
87 local module="$1"
88 get_on_modules | grep -qwF "$module" && return 0
89 echo >&2 "The opennet module name '$module' is unknown - probably misspelled?"
90 echo >&2 "The following module names are known: $(get_on_modules | xargs echo)"
91}
92
93
94## @fn warn_if_not_installed_module()
95## @brief Gib eine Warnung aus, falls das Opennet-Module nicht installiert ist.
96## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
98 local module="$1"
99 is_on_module_installed "$module" && return 0
100 echo >&2 "The opennet module name '$module' is not installed - maybe you want to install it?"
101}
102
103
104## @fn get_on_modules()
105## @brief Liefere die Namen aller bekannten Opennet-Module zeilenweise getrennt zurück.
106## @details Die Liste kann in der Datei ON_CORE_DEFAULTS_FILE angepasst werden.
108 # zeilenweise splitten (wir erwarten nur kleine Buchstaben und Zahlen im Namen)
109 get_on_core_default "on_modules" | sed 's/[^a-z0-9-]/\n/g' | grep -v "^$" || true
110}
111
112
113## @fn get_not_installed_on_modules()
114## @brief Ermittle diejenigen Module, die aktuell nicht installiert sind.
116 local module
117 for module in $(get_on_modules); do
118 is_package_installed "$module" || echo "$module"
119 done
120}
121
122
123## @fn was_on_module_installed_before()
124## @brief Prüfe ob ein Modul "früher" (vor der letzten manuellen Änderung durch den Benutzer) installiert war.
125## @details Diese Prüfung ist hilfreich für die Auswahl von nachträglich zu installierenden Paketen.
126## @param module Name des Opennet-Paketes (siehe 'get_on_modules').
128 local module="$1"
129 uci_is_in_list "on-core.modules.installed" "$module" && return 0
130 trap "" EXIT && return 1
131}
132
133
134## @fn get_missing_modules()
135## @brief Ermittle diejenigen Module, die vor dem letzten Upgrade installiert waren.
137 local module
138 for module in $(get_on_modules); do
139 is_on_module_installed_and_enabled "$module" && continue
140 is_package_installed "$module" && continue
141 was_on_module_installed_before "$module" && echo "$module"
142 true
143 done
144}
145
146
147## @fn install_from_opennet_repository()
148## @param packages Ein oder mehrere zu installierende Software-Pakete
149## @returns Eventuelle Fehlermeldungen werden auf die Standardausgabe geschrieben. Der Exitcode ist immer Null.
150## @brief Installiere ein Paket aus den Opennet-Repositories.
151## @details Für die Installation von Opennet-relevanten Paketen wird eine separate opkg.conf-Datei verwendet.
152## Alle nicht-opennet-relevanten Pakete sollten - wie gewohnt - aus den openwrt-Repositories heraus installiert
153## werden, da deren Paket-Liste umfassender ist.
154## Die opkg.conf wird im tmpfs erzeugt, falls sie noch nicht vorhanden ist. Eventuelle manuelle Nachkorrekturen
155## bleiben also bis zum nächsten Reboot erhalten.
157 trap 'error_trap install_from_opennet_repository "$*"' EXIT
158 local package
159 local not_installed_packages
160 not_installed_packages=$(get_not_installed_on_modules)
161 run_opennet_opkg "update" && run_opennet_opkg "install" "$@"
162 for package in "$@"; do
163 if get_on_modules | grep -qwF "$package"; then
164 # Eventuell schlug die Installation fehl?
165 is_package_installed "$package" || continue
166 # Falls es ein opennet-Modul ist, dann aktiviere es automatisch nach der Installation.
167 # Dies dürfte für den Nutzer am wenigsten überraschend sein.
168 # Wichtig: "enable" in einem neuen Skript-Kontext ausführen, damit sichergestellt ist,
169 # dass die "apply_changes"-Aktion mit den eventuell neuen Funktionen
170 # ausgeführt werden kann.
171 on-function enable_on_module "$package"
172 fi
173 done
174 # wir wollen auch indirekt installierte Pakete aktivieren (z.B. on-openvpn via on-captive-portal)
175 for package in $not_installed_packages; do
176 # unveraendert nicht installiert? Ignorieren ...
177 is_package_installed "$package" || continue
178 on-function enable_on_module "$package"
179 done
180 # anschließend speichern wir den aktuellen Zustand, falls _alle_ Pakete installiert wurden
181 for package in "$@"; do
182 # Paket fehlt? aktuelle Liste nicht speichern, sondern einfach abbrechen
183 is_package_installed "$package" || return 0
184 done
185 save_on_modules_list
186}
187
188
189## @fn remove_opennet_modules()
190## @param module Name der oder des zu entfernenden Modules
191remove_opennet_modules() {
192 # "--force-remove" ist für on-monitoring notwendig, da sonst xinetd wegen einer Änderung
193 # /etc/xinet.d/munin nicht entfernt wird
194 run_opennet_opkg --autoremove --force-remove remove "$@"
195 save_on_modules_list
196}
197
198
199## @fn redirect_to_opkg_opennet_logfile()
200## @brief Führe die gegebene Aktion aus und lenke ihre Ausgabe in die opennet-opkg-Logdatei um.
201## @details Als irrelevant bekannte Meldungen werden herausgefiltert.
202redirect_to_opkg_opennet_logfile() {
203 local log_file
204 log_file=$(get_custom_log_filename "opkg_opennet")
205 "$@" 2>&1 \
206 | grep -vE 'resolve_conffiles: Existing conffile /etc/config/(openvpn|olsrd2) is different from the conffile in the new package\. The new conffile will be placed at /etc/config/(openvpn|olsrd2)-opkg\.' \
207 | grep -v '^Collected errors:$' >>"$log_file"
208}
209
210
211# Ausführung eines opkg-Kommnados mit der opennet-Repository-Konfiguration und minimaler Ausgabe (nur Fehler) auf stdout.
212run_opennet_opkg() {
213 trap 'error_trap run_opennet_opkg "$*"' EXIT
214 # erzeuge Konfiguration, falls sie noch nicht vorhanden ist
215 [ -e "$ON_OPKG_CONF_PATH" ] || generate_opennet_opkg_config >"$ON_OPKG_CONF_PATH"
216 # Vor der opkg-Ausführung müssen wir das Verzeichnis /etc/opkg verdecken, da opkg fehlerhafterweise
217 # auch bei Verwendung von "--conf" die üblichen Orte nach Konfigurationsdateien durchsucht.
218 # TODO: opkg-Bug upstream berichten
219 mount -t tmpfs -o size=32k tmpfs /etc/opkg
220 # opkg ausfuehren und dabei die angegebene Fehlermeldung ignorieren (typisch fuer Paket-Installation nach Upgrade)
221 opkg --verbosity=1 --conf "$ON_OPKG_CONF_PATH" "$@" || true
222 umount /etc/opkg
223}
224
225
226## @fn save_on_modules_list()
227## @brief Speichere die aktuelle Liste der installierten opennet-Module in der uci-Konfiguration.
228## @details Nach einer Aktualisierung ermöglicht diese Sicherung die Nachinstallation fehlender Pakete.
229save_on_modules_list() {
230 local modname
231 _prepare_on_modules
232 [ -z "$(uci_get "on-core.modules")" ] && uci set "on-core.modules=modules"
233 for modname in $(get_on_modules); do
234 if is_package_installed "$modname"; then
235 echo "$modname"
236 fi
237 done | uci_replace_list "on-core.modules.installed"
238 apply_changes on-core
239}
240
241
242## @fn clear_cache_opennet_opkg()
243## @brief Lösche die eventuell vorhandene opennet-opkg-Konfiguration (z.B. nach einem Update).
245 rm -f "$ON_OPKG_CONF_PATH"
246}
247
248
249## @fn get_default_opennet_opkg_repository_base_url()
250## @brief Ermittle die automatisch ermittelte URL für die Nachinstallation von Paketen.
251## @returns Liefert die Basis-URL zurueck. Anzuhängen sind im Anschluss z.B. /packages/${arch_cpu_type} oder /targets/${arch}/generic/packages
253 trap 'error_trap get_default_opennet_opkg_repository_base_url "$*"' EXIT
254 # ermittle die Firmware-Repository-URL
255 local firmware_version
256 firmware_version=$(get_on_firmware_version)
257 # leere Versionsnummer? Damit können wir nichts anfangen.
258 [ -z "$firmware_version" ] && msg_error "Failed to retrieve opennet firmware version for opkg repository URL" && return 0
259 # snapshots erkennen wir aktuell daran, dass auch Buchstaben in der Versionsnummer vorkommen
260 local version_path
261 if echo "$firmware_version" | grep -q "[a-zA-Z]"; then
262 # ein Buchstabe wurde entdeckt: unstable
263 version_path="testing/$firmware_version"
264 else
265 # kein Buchstabe wurde entdeckt: stable
266 # wir schneiden alles ab dem ersten Bindestrich ab
267 version_path="stable/$(echo "$firmware_version" | cut -f 1 -d -)"
268 fi
269 echo "$ON_OPKG_REPOSITORY_URL_PREFIX/$version_path"
270}
271
272
273## @fn get_configured_opennet_opkg_repository_base_url()
274## @brief Ermittle die aktuell konfigurierte Repository-URL.
276 local url
277 _prepare_on_modules
278 url=$(uci_get "on-core.modules.repository_url")
279 if [ -n "$url" ]; then
280 echo "$url"
281 else
283 fi
284}
285
286
287## @fn set_configured_opennet_opkg_repository_url()
288## @param repo_url Die neue Repository-URL (bis einschliesslich "/packages").
289## @brief Ändere die aktuell konfigurierte Repository-URL.
290## @details Die URL wird via uci gespeichert. Falls sie identisch mit der Standard-URL ist, wird die Einstellung gelöscht.
292 local repo_url="$1"
293 _prepare_on_modules
294 if [ -z "$repo_url" ] || [ "$repo_url" = "$(get_default_opennet_opkg_repository_base_url "opennet")" ]; then
295 # Standard-Wert: loeschen
296 uci_delete "on-core.modules.repository_url"
297 else
298 uci set "on-core.modules.repository_url=$repo_url"
299 fi
301}
302
303
304## @fn generate_opennet_opkg_config()
305## @brief Liefere den Inhalt einer opkg.conf für das Opennet-Paket-Repository zurück.
306## @details Die aktuelle Version wird aus dem openwrt-Versionsstring gelesen.
308 trap 'error_trap generate_opennet_opkg_config "$*"' EXIT
309 # schreibe den Inahlt der neuen OPKG-Konfiguration
310 echo "dest root /"
311 echo "dest ram /tmp"
312 echo "lists_dir ext /var/opkg-lists-opennet"
313 echo "option overlay_root /overlay"
314 echo
315
316 local base_url
318
319 # Füge non-core package hinzu (z.B. feeds routing,opennet,luci,...)
320 # Hole Architektur und CPU Type
321 local arch_cpu_type
322 arch_cpu_type=$(opkg status base-files | awk '/Architecture/ {print $2}')
323 local noncore_pkgs_url="$base_url/packages/$arch_cpu_type"
324
325 local feed
326 for feed in base packages routing luci opennet; do
327 echo "src/gz on_$feed $noncore_pkgs_url/$feed"
328 done
329
330 # Fuege zusaetzlich eine URL mit core packages hinzu (beinhaltet Kernel Module).
331 local arch_path
332 # shellcheck source=openwrt/package/base-files/files/etc/openwrt_release
333 arch_path=$(. /etc/openwrt_release; echo "$DISTRIB_TARGET")
334 local core_pkgs_url="$base_url/targets/$arch_path/packages"
335 echo "src/gz on_core $core_pkgs_url"
336}
337
338
339## @fn is_package_installed()
340## @brief Prüfe, ob ein opkg-Paket installiert ist.
341## @param package Name des Pakets
343 trap 'error_trap is_package_installed "$*"' EXIT
344 local package="$1"
345 local status
346 # Korrekte Prüfung: via "opkg list-installed" - leider erzeugt sie locking-Fehlermeldung
347 # bei parallelen Abläufen (z.B. Status-Seite).
348 #opkg list-installed | grep -q -w "^$package" && return 0
349 # schneller als via opkg
350 status=$(grep -A 10 "^Package: $package$" "${IPKG_INSTROOT:-}/usr/lib/opkg/status" \
351 | grep "^Status:" | head -1 | cut -f 2- -d :)
352 [ -z "$status" ] && trap "" EXIT && return 1
353 echo "$status" | grep -qE "(deinstall|not-installed)" && trap "" EXIT && return 1
354 return 0
355}
356
357
358## @fn on_opkg_postinst_default()
359## @brief Übliche Nachbereitung einer on-Paket-Installation.
360## @details Caches löschen, uci-defaults anwenden, on-core-Bootskript ausführen
362 # Reset des Luci-Cache und Shell-Cache
363 clear_caches
364 # Paket-Initialisierungen durchfuehren, falls wir in einem echten System sind.
365 # In der Paket-Bau-Phase funktioniert die untenstehende Aktion nicht, da eine
366 # Datei fehlt, die in der /etc/init.d/boot geladen wird.
367 if [ -z "${IPKG_INSTROOT:-}" ]; then
368 msg_info "Applying uci-defaults after package installation"
369 # Die Angabe von IPKG_INSTROOT ist hier muessig - aber vielleicht
370 # koennen wir die obige Bedingung irgendwann entfernen.
371 (
372 # der Rest sollte ohne Vorsicht stattfinden
373 set +eu
374 # shellcheck source=openwrt/package/base-files/files/etc/init.d/boot
375 . "${IPKG_INSTROOT:-}/etc/init.d/boot"
376 uci_apply_defaults
377 # Boot-Skript aktivieren und ausführen (falls noch nicht geschehen)
378 /etc/init.d/on-core enable 2>/dev/null || true
379 /etc/init.d/on-core start
380 set -eu
381 )
382 fi
384}
385
386
387## @fn on_opkg_postrm_default()
388## @brief Übliche Nachbereitung einer on-Paket-Entfernung
389## @details Caches löschen
391 clear_caches
393}
394
395# Ende der Doku-Gruppe
396## @}
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
Definition: core.sh:22
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
Definition: core.sh:15
done
Definition: core.sh:85
clean_luci_restart()
Starte den Webserver neu und lösche alle luci-Cache-Dateien und Kompilate.
Definition: devel.sh:11
is_on_module_installed(module)
Pruefe ob ein Opennet-Modul installiert ist.
Definition: modules.sh:13
get_missing_modules()
Ermittle diejenigen Module, die vor dem letzten Upgrade installiert waren.
Definition: modules.sh:46
get_on_modules()
Liefere die Namen aller bekannten Opennet-Module zeilenweise getrennt zurück.
Definition: modules.sh:35
was_on_module_installed_before()
Prüfe ob ein Modul "früher" (vor der letzten manuellen Änderung durch den Benutzer,...
Definition: modules.sh:43
get_default_opennet_opkg_repository_base_url()
Ermittle die automatisch ermittelte URL für die Nachinstallation von Paketen.
Definition: modules.sh:74
is_package_installed(package)
Prüfe, ob ein opkg-Paket installiert ist.
Definition: modules.sh:90
warn_if_unknown_module(module)
Gib eine Warnung aus, falls der angegebene Modul-Name unbekannt ist.
Definition: modules.sh:27
generate_opennet_opkg_config()
Liefere den Inhalt einer opkg.conf für das Opennet-Paket-Repository zurück.
Definition: modules.sh:86
on_opkg_postinst_default()
Übliche Nachbereitung einer on-Paket-Installation.
Definition: modules.sh:94
disable_on_module(module)
Deaktiviere ein Opennet-Modul.
Definition: modules.sh:21
set_configured_opennet_opkg_repository_url(repo_url)
Ändere die aktuell konfigurierte Repository-URL.
Definition: modules.sh:82
is_on_module_installed_and_enabled(module)
Pruefe ob ein Opennet-Modul sowohl installiert, als auch aktiviert ist.
Definition: modules.sh:9
on_opkg_postrm_default()
Übliche Nachbereitung einer on-Paket-Entfernung.
Definition: modules.sh:98
install_from_opennet_repository(packages)
Installiere ein Paket aus den Opennet-Repositories.
Definition: modules.sh:56
clear_cache_opennet_opkg()
Lösche die eventuell vorhandene opennet-opkg-Konfiguration (z.B. nach einem Update).
Definition: modules.sh:70
warn_if_not_installed_module(module)
Gib eine Warnung aus, falls das Opennet-Module nicht installiert ist.
Definition: modules.sh:31
get_not_installed_on_modules()
Ermittle diejenigen Module, die aktuell nicht installiert sind.
Definition: modules.sh:38
get_configured_opennet_opkg_repository_base_url()
Ermittle die aktuell konfigurierte Repository-URL.
Definition: modules.sh:77
enable_on_module(module)
Aktiviere ein Opennet-Modul.
Definition: modules.sh:17
uci_is_in_list(uci_path, item)
Prüfe ob ein Element in einer Liste vorkommt.
Definition: uci.sh:27
uci_delete(uci_path)
Lösche ein UCI-Element.
Definition: uci.sh:46
uci_replace_list()
Replace the items in a list. Wanted items are expected via stdin (one per line, uci_path).
Definition: uci.sh:41
uci_add_list(uci_path, new_item)
Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
Definition: uci.sh:10
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
Definition: uci.sh:33
set eu grep root::etc shadow exit if command v chpasswd dev null
Definition: on-password:12
set eu on function print_services services log for dir in etc on services d var on services volatile d
Definition: services:13