Opennet Firmware
 Alle Dateien Funktionen Variablen Gruppen Seiten
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
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"
11 
12 
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
20  local module="$1"
21  is_package_installed "$module" && _is_on_module_enabled "$module" && return 0
22  trap "" $GUARD_TRAPS && return 1
23 }
24 
25 
26 _is_on_module_enabled() {
27  local module="$1"
28  uci_is_in_list "on-core.modules.enabled" "$module" && return 0
29  trap "" $GUARD_TRAPS && return 1
30 }
31 
32 
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
38  local module="$1"
39  _is_on_module_enabled "$module" && return 0
40  [ -z "$(uci_get "on-core.modules")" ] && uci set "on-core.modules=modules"
41  uci_add_list "on-core.modules.enabled" "$module"
42  apply_changes "on-core" "$module"
43 }
44 
45 
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
51  local module="$1"
52  _is_on_module_enabled "$module" || return 0
53  uci_delete_list "on-core.modules.enabled" "$module"
54  apply_changes "on-core" "$module"
55 }
56 
57 
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 "^$"
64 }
65 
66 
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.
71  local module="$1"
72  uci_is_in_list "on-core.modules.installed" "$module" && return 0
73  trap "" $GUARD_TRAPS && return 1
74 }
75 
76 
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
88  local package
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.
96  enable_on_module "$package"
97  fi
98  done
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
103  done
104  save_on_modules_list
105 }
106 
107 
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 "$@"
113  save_on_modules_list
114 }
115 
116 
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:$" \
131  || true
132  umount /etc/opkg
133 }
134 
135 
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() {
140  local modname
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" \
145  || uci_delete_list "on-core.modules.installed" "$modname"
146  done
147  apply_changes on-core
148 }
149 
150 
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"
155 }
156 
157 
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"
165  local prefix
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"
170  else
171  msg_info "Invalid opkg repository target zone requested: $target_zone"
172  # sinnvolle Rueckfalloption verwenden
173  prefix="$ON_OPKG_REPOSITORY_URL_PREFIX_OPENNET"
174  fi
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
181  local version_path
182  if echo "$firmware_version" | grep -q "[a-zA-Z]"; then
183  # ein Buchstabe wurde entdeckt: unstable
184  version_path="testing/$firmware_version"
185  else
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 -)"
189  fi
190  # Hole "DISTRIB_TARGET" und entferne potentielle "/generic"-Suffixe (z.B. ar71xx und x86),
191  # da wir dies in unserem Repository nicht abbilden.
192  local arch_path
193  arch_path=$(. /etc/openwrt_release; echo "$DISTRIB_TARGET" | sed 's#/generic$##')
194  echo "$prefix/$version_path/$arch_path/packages"
195 }
196 
197 
198 ## @fn get_configured_opennet_opkg_repository_url()
199 ## @brief Ermittle die aktuell konfigurierte Repository-URL.
200 get_configured_opennet_opkg_repository_url() {
201  local prefix
202  prefix=$(uci_get "on-core.modules.repository_url")
203  [ -n "$prefix" ] && echo "$prefix" || get_default_opennet_opkg_repository_url "opennet"
204 }
205 
206 
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() {
212  local repo_url="$1"
213  if [ -z "$repo_url" ] || [ "$repo_url" = "$(get_default_opennet_opkg_repository_url "opennet")" ]; then
214  # Standard-Wert: loeschen
215  uci_delete "on-core.modules.repository_url"
216  else
217  uci set "on-core.modules.repository_url=$repo_url"
218  fi
219  clear_cache_opennet_opkg
220 }
221 
222 
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
230  echo "dest root /"
231  echo "dest ram /tmp"
232  echo "lists_dir ext /var/opkg-lists-opennet"
233  echo "option overlay_root /overlay"
234  echo
235  local feed
236  for feed in base packages routing telephony luci opennet; do
237  echo "src/gz on_$feed $repository_url/$feed"
238  done
239 }
240 
241 
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() {
246  local package="$1"
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
253 }
254 
255 
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
261  clear_caches
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.
269  (
270  # der Rest sollte ohne Vorsicht stattfinden
271  set +eu
272  . "${IPKG_INSTROOT:-}/etc/init.d/boot"
273  uci_apply_defaults
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
277  set -eu
278  )
279  fi
281 }
282 
283 
284 ## @fn on_opkg_postrm_default()
285 ## @brief Übliche Nachbereitung einer on-Paket-Entfernung
286 ## @details Caches löschen
287 on_opkg_postrm_default() {
288  clear_caches
290 }
291 
292 # Ende der Doku-Gruppe
293 ## @}
get_on_modules()
Liefere die Namen aller bekannten Opennet-Module zeilenweise getrennt zurück.
Definition: modules.sh:21
uci_delete(uci_path)
Lösche ein UCI-Element.
Definition: uci.sh:38
uci_is_in_list(uci_path, item)
Prüfe ob ein Element in einer Liste vorkommt.
Definition: uci.sh:27
enable_on_module(module)
Aktiviere ein Opennet-Modul.
Definition: modules.sh:13
disable_on_module(module)
Deaktiviere ein Opennet-Modul.
Definition: modules.sh:17
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
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
Definition: core.sh:15
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
Definition: uci.sh:33
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
Definition: core.sh:22
set eu grep root::etc shadow exit if which chpasswd dev null
Definition: on-password:12
done
Definition: core.sh:81
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.
Definition: modules.sh:9
was_on_module_installed_before()
Prüfe ob ein Modul "früher" (vor der letzten manuellen Änderung durch den Benutzer) installiert war...
Definition: modules.sh:25
clean_luci_restart()
Starte den Webserver neu und lösche alle luci-Cache-Dateien und Kompilate.
Definition: devel.sh:11
install_from_opennet_repository(packages)
Installiere ein Paket aus den Opennet-Repositories.
Definition: modules.sh:35