1 ## @defgroup modules Module
2 ## @brief Verwaltung der Opennet-Module für verschiedene Funktionen/Rollen
3 # Beginn der Doku-Gruppe
6 # Basis-URL für Opennet-Paketinstallationen
7 ON_OPKG_REPOSITORY_URL_PREFIX_OPENNET=
"http://downloads.on/openwrt"
8 ON_OPKG_REPOSITORY_URL_PREFIX_INTERNET=
"http://downloads.opennet-initiative.de/openwrt"
9 # temporäre Datei für Installation von Opennet-Paketen
10 ON_OPKG_CONF_PATH=
"${IPKG_INSTROOT:-}/tmp/opkg-opennet.conf"
13 ## @fn is_on_module_installed_and_enabled()
14 ## @brief Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.
15 ## @param module Eins der Opennet-Pakete (siehe 'get_on_modules').
16 ## @details Die Aktivierung eines Modules wird anhand der uci-Einstellung "${module}.settings.enabled" geprueft.
17 ## Der Standardwert ist "false" (ausgeschaltet).
19 trap
"error_trap is_on_module_installed_and_enabled '$*'" $GUARD_TRAPS
21 is_package_installed
"$module" && _is_on_module_enabled
"$module" &&
return 0
22 trap
"" $GUARD_TRAPS &&
return 1
26 _is_on_module_enabled() {
29 trap
"" $GUARD_TRAPS &&
return 1
33 ## @fn enable_on_module()
34 ## @brief Aktiviere ein Opennet-Modul
35 ## @param module Eins der Opennet-Pakete (siehe 'get_on_modules').
37 trap
"error_trap enable_on_module '$*'" $GUARD_TRAPS
39 _is_on_module_enabled
"$module" &&
return 0
40 [ -z
"$(uci_get "on-core.modules
")" ] && uci set
"on-core.modules=modules"
42 apply_changes
"on-core" "$module"
46 ## @fn disable_on_module()
47 ## @brief Deaktiviere ein Opennet-Modul
48 ## @param module Eins der Opennet-Pakete (siehe 'get_on_modules').
50 trap
"error_trap disable_on_module '$*'" $GUARD_TRAPS
52 _is_on_module_enabled
"$module" ||
return 0
54 apply_changes
"on-core" "$module"
58 ## @fn get_on_modules()
59 ## @brief Liefere die Namen aller bekannten Opennet-Module zeilenweise getrennt zurück.
60 ## @details Die Liste kann in der Datei ON_CORE_DEFAULTS_FILE angepasst werden.
62 # zeilenweise splitten (wir erwarten nur kleine Buchstaben im Namen)
63 get_on_core_default
"on_modules" | sed
's/[^a-z-]/\n/g' | grep -v
"^$"
67 ## @fn was_on_module_installed_before()
68 ## @brief Prüfe ob ein Modul "früher" (vor der letzten manuellen Änderung durch den Benutzer) installiert war.
69 ## @details Diese Prüfung ist hilfreich für die Auswahl von nachträglich zu installierenden Paketen.
73 trap
"" $GUARD_TRAPS &&
return 1
77 ## @fn install_from_opennet_repository()
78 ## @param packages Ein oder mehrere zu installierende Software-Pakete
79 ## @returns Eventuelle Fehlermeldungen werden auf die Standardausgabe geschrieben. Der Exitcode ist immer Null.
80 ## @brief Installiere ein Paket aus den Opennet-Repositories.
81 ## @details Für die Installation von Opennet-relevanten Paketen wird eine separate opkg.conf-Datei verwendet.
82 ## Alle nicht-opennet-relevanten Pakete sollten - wie gewohnt - aus den openwrt-Repositories heraus installiert
83 ## werden, da deren Paket-Liste umfassender ist.
84 ## Die opkg.conf wird im tmpfs erzeugt, falls sie noch nicht vorhanden ist. Eventuelle manuelle Nachkorrekturen
85 ## bleiben also bis zum nächsten Reboot erhalten.
87 trap
"error_trap install_from_opennet_repository '$*'" $GUARD_TRAPS
89 _run_opennet_opkg "update" && _run_opennet_opkg "install" "$
@"
90 for package in "$
@"; do
91 if get_on_modules | grep -qwF "$package"; then
92 # Eventuell schlug die Installation fehl?
93 is_package_installed
"$package" ||
continue
94 # Falls es ein opennet-Modul ist, dann aktiviere es automatisch nach der Installation.
95 # Dies dürfte für den Nutzer am wenigsten überraschend sein.
99 # anschließend speichern wir den aktuellen Zustand, falls _alle_ Pakete installiert wurden
100 for package in "$
@"; do
101 # Paket fehlt? aktuelle Liste nicht speichern, sondern einfach abbrechen
102 is_package_installed "$package" || return 0
108 ## @fn remove_opennet_module()
109 ## @param module Name des oder der zu entfernenden Module
110 remove_opennet_modules() {
111 local log_file=$(get_custom_log_filename "opkg_opennet")
112 _run_opennet_opkg --autoremove remove "$
@"
117 # Ausführung eines opkg-Kommnados mit der opennet-Repository-Konfiguration und minimaler Ausgabe (nur Fehler) auf stdout.
118 _run_opennet_opkg() {
119 trap "error_trap _run_opennet_opkg '$*'" $GUARD_TRAPS
120 # erzeuge Konfiguration, falls sie noch nicht vorhanden ist
121 [ -e "$ON_OPKG_CONF_PATH" ] || generate_opennet_opkg_config >"$ON_OPKG_CONF_PATH"
122 local log_file=$(get_custom_log_filename "opkg_opennet")
123 # Vor der opkg-Ausführung müssen wir das Verzeichnis /etc/opkg verdecken, da opkg fehlerhafterweise
124 # auch bei Verwendung von "--conf" die üblichen Orte nach Konfigurationsdateien durchsucht.
125 # TODO: opkg-Bug upstream berichten
126 mount -t tmpfs -o size=32k tmpfs /etc/opkg
127 # opkg ausfuehren und dabei die angegebene Fehlermeldung ignorieren (typisch fuer Paket-Installation nach Upgrade)
128 opkg --verbosity=1 --conf "$ON_OPKG_CONF_PATH" "$
@" >>"$log_file" 2>&1 \
129 | grep -vF "resolve_conffiles: Existing conffile /etc/config/openvpn is different from the conffile in the new package. The new conffile will be placed at /etc/config/openvpn-opkg." \
130 | grep -v "^Collected errors:$" \
136 ## @fn save_on_modules_list()
137 ## @brief Speichere die aktuelle Liste der installierten opennet-Module in der uci-Konfiguration.
138 ## @details Nach einer Aktualisierung ermöglicht diese Sicherung die Nachinstallation fehlender Pakete.
139 save_on_modules_list() {
141 [ -z "$(uci_get "on-core.modules")" ] && uci set "on-core.modules=modules"
142 get_on_modules | while read modname;
do
143 is_package_installed
"$modname" \
144 &&
uci_add_list "on-core.modules.installed" "$modname" \
147 apply_changes on-core
151 ## @fn clear_cache_opennet_opkg()
152 ## @brief Lösche die eventuell vorhandene opennet-opkg-Konfiguration (z.B. nach einem Update).
153 clear_cache_opennet_opkg() {
154 rm -f
"$ON_OPKG_CONF_PATH"
158 ## @fn get_default_opennet_opkg_repository_url()
159 ## @param target_zone Entweder "internet" oder "opennet".
160 ## @brief Ermittle die automatisch ermittelte URL für die Nachinstallation von Paketen.
161 ## @returns Liefert die Basis-URL bis einschließlich "/packages". Lediglich der Feed-Name ist anzuhängen.
162 get_default_opennet_opkg_repository_url() {
163 trap
"error_trap get_default_opennet_opkg_repository_url '$*'" $GUARD_TRAPS
164 local target_zone=
"$1"
166 if [
"$target_zone" =
"opennet" ]; then
167 prefix=
"$ON_OPKG_REPOSITORY_URL_PREFIX_OPENNET"
168 elif [
"$target_zone" =
"internet" ]; then
169 prefix=
"$ON_OPKG_REPOSITORY_URL_PREFIX_INTERNET"
171 msg_info "Invalid opkg repository target zone requested: $target_zone"
172 # sinnvolle Rueckfalloption verwenden
173 prefix=
"$ON_OPKG_REPOSITORY_URL_PREFIX_OPENNET"
175 # ermittle die Firmware-Repository-URL
176 local firmware_version
177 firmware_version=$(get_on_firmware_version)
178 # leere Versionsnummer? Damit können wir nichts anfangen.
179 [ -z
"$firmware_version" ] &&
msg_error "Failed to retrieve opennet firmware version for opkg repository URL" &&
return 0
180 # snapshots erkennen wir aktuell daran, dass auch Buchstaben in der Versionsnummer vorkommen
182 if echo
"$firmware_version" | grep -q
"[a-zA-Z]"; then
183 # ein Buchstabe wurde entdeckt: unstable
184 version_path=
"testing/$firmware_version"
186 # kein Buchstabe wurde entdeckt: stable
187 # wir schneiden alles ab dem ersten Bindestrich ab
188 version_path=
"stable/$(echo "$firmware_version
" | cut -f 1 -d -)"
190 # Hole
"DISTRIB_TARGET" und entferne potentielle
"/generic"-Suffixe (z.B. ar71xx und x86),
191 # da wir dies in unserem Repository nicht abbilden.
193 arch_path=$(. /etc/openwrt_release; echo
"$DISTRIB_TARGET" | sed
's#/generic$##')
194 echo
"$prefix/$version_path/$arch_path/packages"
198 ## @fn get_configured_opennet_opkg_repository_url()
199 ## @brief Ermittle die aktuell konfigurierte Repository-URL.
200 get_configured_opennet_opkg_repository_url() {
202 prefix=$(uci_get
"on-core.modules.repository_url")
203 [ -n
"$prefix" ] && echo
"$prefix" || get_default_opennet_opkg_repository_url
"opennet"
207 ## @fn set_configured_opennet_opkg_repository_url()
208 ## @param repo_url Die neue Repository-URL (bis einschliesslich "/packages").
209 ## @brief Ändere die aktuell konfigurierte Repository-URL.
210 ## @details Die URL wird via uci gespeichert. Falls sie identisch mit der Standard-URL ist, wird die Einstellung gelöscht.
211 set_configured_opennet_opkg_repository_url() {
213 if [ -z
"$repo_url" ] || [
"$repo_url" =
"$(get_default_opennet_opkg_repository_url "opennet
")" ]; then
214 # Standard-Wert: loeschen
217 uci set
"on-core.modules.repository_url=$repo_url"
219 clear_cache_opennet_opkg
223 ## @fn generate_opennet_opkg_config()
224 ## @brief Liefere den Inhalt einer opkg.conf für das Opennet-Paket-Repository zurück.
225 ## @details Die aktuelle Version wird aus dem openwrt-Versionsstring gelesen.
226 generate_opennet_opkg_config() {
227 trap
"error_trap generate_opennet_opkg_config '$*'" $GUARD_TRAPS
228 local repository_url=
"$(get_configured_opennet_opkg_repository_url)"
229 # schreibe den Inahlt der neuen OPKG-Konfiguration
232 echo
"lists_dir ext /var/opkg-lists-opennet"
233 echo
"option overlay_root /overlay"
236 for feed in base packages routing telephony luci opennet;
do
237 echo
"src/gz on_$feed $repository_url/$feed"
242 ## @fn is_package_installed()
243 ## @brief Prüfe, ob ein opkg-Paket installiert ist.
244 ## @param package Name des Pakets
245 is_package_installed() {
247 # Korrekte Prüfung: via "opkg list-installed" - leider erzeugt sie locking-Fehlermeldung
248 # bei parallelen Abläufen (z.B. Status-Seite).
249 #opkg list-installed | grep -q -w "^$package" && return 0
250 # schneller als via opkg
251 [ -e
"${IPKG_INSTROOT:-}/usr/lib/opkg/info/${package}.control" ] &&
return 0
252 trap
"" $GUARD_TRAPS &&
return 1
256 ## @fn on_opkg_postinst_default()
257 ## @brief Übliche Nachbereitung einer on-Paket-Installation.
258 ## @details Caches löschen, uci-defaults anwenden, on-core-Bootskript ausführen
259 on_opkg_postinst_default() {
260 # Reset des Luci-Cache und Shell-Cache
262 # Paket-Initialisierungen durchfuehren, falls wir in einem echten System sind.
263 # In der Paket-Bau-Phase funktioniert die untenstehende Aktion nicht, da eine
264 # Datei fehlt, die in der /etc/init.d/boot geladen wird.
265 if [ -z
"${IPKG_INSTROOT:-}" ]; then
266 msg_info "Applying uci-defaults after package installation"
267 # Die Angabe von IPKG_INSTROOT ist hier muessig - aber vielleicht
268 # koennen wir die obige Bedingung irgendwann entfernen.
270 # der Rest sollte ohne Vorsicht stattfinden
272 .
"${IPKG_INSTROOT:-}/etc/init.d/boot"
274 # Boot-Skript aktivieren und ausführen (falls noch nicht geschehen)
275 /etc/init.d/on-core enable 2>/dev/
null ||
true
276 /etc/init.d/on-core start
284 ## @fn on_opkg_postrm_default()
285 ## @brief Übliche Nachbereitung einer on-Paket-Entfernung
286 ## @details Caches löschen
287 on_opkg_postrm_default() {
292 # Ende der Doku-Gruppe
get_on_modules()
Liefere die Namen aller bekannten Opennet-Module zeilenweise getrennt zurück.
uci_delete(uci_path)
Lösche ein UCI-Element.
uci_is_in_list(uci_path, item)
Prüfe ob ein Element in einer Liste vorkommt.
enable_on_module(module)
Aktiviere ein Opennet-Modul.
disable_on_module(module)
Deaktiviere ein Opennet-Modul.
uci_add_list(uci_path, new_item)
Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
set eu grep root::etc shadow exit if which chpasswd dev null
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.
was_on_module_installed_before()
Prüfe ob ein Modul "früher" (vor der letzten manuellen Änderung durch den Benutzer) installiert war...
clean_luci_restart()
Starte den Webserver neu und lösche alle luci-Cache-Dateien und Kompilate.
install_from_opennet_repository(packages)
Installiere ein Paket aus den Opennet-Repositories.