diff --git a/net/etebase/Makefile b/net/etebase/Makefile new file mode 100644 index 000000000..ebcda301b --- /dev/null +++ b/net/etebase/Makefile @@ -0,0 +1,112 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=etebase +PKG_VERSION:=0.6.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=etebase-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/etesync/server/archive/v$(PKG_VERSION) +PKG_HASH:=4832c35fa1b46936bfde894a8c888989e9a37dd64ca588df22524825f3e568ec + +PKG_LICENSE:=AGPL-3.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Peter Stadler + +PKG_BUILD_PARALLEL:=1 +PYTHON3_PKG_BUILD:=0 + +PKG_UNPACK=$(HOST_TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE) + +include $(INCLUDE_DIR)/package.mk +include ../../lang/python/python3-package.mk + + +define Package/etebase + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=End-to-end encrypted backend + URL:=https://www.etebase.com/ + DEPENDS:=+nginx-ssl +uwsgi +uwsgi-syslog-plugin +uwsgi-python3-plugin +python3-light \ + +python3-asgiref +python3-cffi +python3-django-cors-headers +python3-django \ + +python3-django-restframework +python3-drf-nested-routers +python3-msgpack \ + +python3-pycparser +python3-pynacl +python3-pytz +python3-six +python3-sqlparse + # +psycopg2-binary would be needed for using postgres db. + USERID:=etebase=44312 +endef + + +define Package/etebase/description + End-to-end encrypted backend +endef + + +Build/Compile:=: + + +define Py3Package/etebase/install + # OpenWrt specific: + $(INSTALL_DIR) $(1)/etc/uci-defaults/ + $(CP) ./files/81_setup-etebase $(1)/etc/uci-defaults/ + + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/uwsgi.init $(1)/etc/init.d/etebase + + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) ./files/uci.cfg $(1)/etc/config/etebase + + # Server configuration: + $(INSTALL_DIR) $(1)/etc/nginx/conf.d/ + $(INSTALL_CONF) ./files/etebase.locations $(1)/etc/nginx/conf.d/ + + $(INSTALL_DIR) $(1)/etc/uwsgi/vassals/ + $(INSTALL_CONF) ./files/uwsgi.ini $(1)/etc/uwsgi/vassals/etebase.available + #init links etebase.available /var/etc/etebase/uwsgi.ini: + $(LN) /var/etc/etebase/uwsgi.ini $(1)/etc/uwsgi/vassals/etebase.ini + + # Upstream application: + $(INSTALL_DIR) $(1)/usr/share/etebase/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/manage.py $(1)/usr/share/etebase/ + #init creates /var/etc/etebase/server.ini from uci.cfg: + $(LN) /var/etc/etebase/server.ini $(1)/usr/share/etebase/etebase-server.ini + + $(INSTALL_DIR) $(1)/usr/share/etebase/django_etebase/ + $(CP) $(PKG_BUILD_DIR)/django_etebase/* $(1)/usr/share/etebase/django_etebase/ + + $(INSTALL_DIR) $(1)/usr/share/etebase/etebase_server/ + $(CP) $(PKG_BUILD_DIR)/etebase_server/* $(1)/usr/share/etebase/etebase_server/ + + $(INSTALL_DIR) $(1)/usr/share/etebase/myauth/ + $(CP) $(PKG_BUILD_DIR)/myauth/* $(1)/usr/share/etebase/myauth/ + + $(INSTALL_DIR) $(1)/usr/share/etebase/templates/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/templates/* $(1)/usr/share/etebase/templates/ + + $(INSTALL_DIR) $(1)/www/etebase/static/ +endef + + +Py3Package/etebase/filespec:= + + +define Package/etebase/postrm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +cd /usr/share/etebase/ && rmdir */*/*/*/* */*/*/* */*/* */* * 2>/dev/null +[ "$${PKG_UPGRADE}" = "1" ] && exit 0 +rm -r /www/etebase/static +rmdir --ignore-fail-on-non-empty /www/etebase /var/etc/etebase +exit 0 +endef + + +define Package/etebase/conffiles +/etc/config/etebase +/etc/nginx/conf.d/etebase.locations +/etc/uwsgi/vassals/etebase.available +endef + + +$(eval $(call Py3Package,etebase)) +$(eval $(call BuildPackage,etebase)) +$(eval $(call BuildPackage,etebase-src)) diff --git a/net/etesync-server/files/81_setup-etesync-server b/net/etebase/files/81_setup-etebase similarity index 73% rename from net/etesync-server/files/81_setup-etesync-server rename to net/etebase/files/81_setup-etebase index d693e1713..4cf4fa642 100644 --- a/net/etesync-server/files/81_setup-etesync-server +++ b/net/etebase/files/81_setup-etebase @@ -1,30 +1,30 @@ #!/bin/sh -cd /usr/share/etesync-server || exit 1 +cd /usr/share/etebase || exit 1 python3 manage.pyc migrate --noinput || exit 1 # setup minimal ini for collectstatic: -mkdir -p /var/etc/etesync-server/ || exit 1 -printf "[global]\nSTATIC_ROOT=/www/etesync/static" >etesync-server.ini || exit 1 +mkdir -p /var/etc/etebase/ || exit 1 +printf "[global]\nSTATIC_ROOT=/www/etebase/static" >etebase-server.ini || exit 1 python3 manage.pyc collectstatic --noinput || exit 1 -ETESYNC_HAS_USER_PY3CMD="import sqlite3 +ETEBASE_HAS_USER_PY3CMD="import sqlite3 c = sqlite3.connect('db.sqlite3').cursor() -c.execute('select * from auth_user') +c.execute('select * from myauth_user;') if c.fetchone()==None: print('0') else: print('1')" echo -if [ "$(python3 -c "$ETESYNC_HAS_USER_PY3CMD" || exit 1)" = "0" ] +if [ "$(python3 -c "$ETEBASE_HAS_USER_PY3CMD" || exit 1)" = "0" ] then echo "===== First, create a superuser of the Webinterface by =====" [ -t 0 ] && python3 manage.pyc createsuperuser || echo "===== python3 $(pwd)/manage.pyc createsuperuser =====" fi -chown -Rh etesync:nogroup . /www/etesync/ || exit 1 +chown -Rh etebase:nogroup . /www/etebase/ || exit 1 [ -x /etc/init.d/nginx ] || exit 1 @@ -49,6 +49,6 @@ router_ip() { echo '$ROUTER' } -echo "===== You can add users by https://$(router_ip)/etesync/admin/login =====" +echo "===== You can add users by https://$(router_ip)/etebase/admin/login =====" exit 0 diff --git a/net/etebase/files/etebase.locations b/net/etebase/files/etebase.locations new file mode 100644 index 000000000..5ef044190 --- /dev/null +++ b/net/etebase/files/etebase.locations @@ -0,0 +1,20 @@ +location /etebase/static { + access_log off; + error_log /dev/null; + expires 1y; + try_files $uri $uri/ =404; +} + +location /etebase/media { + access_log off; + error_log /dev/null; + expires 1y; + try_files $uri $uri/ =404; +} + +location /etebase { + access_log off; + error_log /dev/null; + include uwsgi_params; + uwsgi_pass unix:///var/run/etebase.socket; +} diff --git a/net/etesync-server/files/uci.cfg b/net/etebase/files/uci.cfg similarity index 100% rename from net/etesync-server/files/uci.cfg rename to net/etebase/files/uci.cfg diff --git a/net/etesync-server/files/uwsgi.ini b/net/etebase/files/uwsgi.ini similarity index 69% rename from net/etesync-server/files/uwsgi.ini rename to net/etebase/files/uwsgi.ini index f27542976..570047f06 100644 --- a/net/etesync-server/files/uwsgi.ini +++ b/net/etebase/files/uwsgi.ini @@ -1,17 +1,17 @@ -; The script /etc/init.d/etesync-server creates the second symlink in the +; The script /etc/init.d/etebase creates the second symlink in the ; following chain when starting (and deletes it when stopping the service): -; /etc/uwsgi/vassals/etesync-server.ini (letting the emperor load it on-demand) -; -> /var/etc/etesync-server/uwsgi.ini (in RAM) -; -> /etc/uwsgi/vassals/etesync-server.available (this file) +; /etc/uwsgi/vassals/etebase.ini (letting the emperor load it on-demand) +; -> /var/etc/etebase/uwsgi.ini (in RAM) +; -> /etc/uwsgi/vassals/etebase.available (this file) [uwsgi] strict = true plugin = python manage-script-name = true -chdir = /usr/share/etesync-server -mount = /etesync=etesync_server.wsgi:application -pidfile = /var/etc/etesync-server/master.pid +chdir = /usr/share/etebase +mount = /etebase=etebase_server.wsgi:application +pidfile = /var/etc/etebase/master.pid enable-threads = true thunder-lock = true @@ -25,24 +25,24 @@ plugin = syslog ; disable-logging only affects req-logger: disable-logging = true log-format=%(method) %(uri) => return %(status) (%(rsize) bytes in %(msecs) ms) -req-logger = syslog:etesync-server_req +req-logger = syslog:etebase_req -logger = etesync syslog:etesync-server_main +logger = etebase syslog:etebase_main ignore-sigpipe = true ignore-write-errors = true if-env = UWSGI_EMPEROR_FD ; the regular expression leaves for successful de/activation only one line each: -log-route = etesync ^(?!... Starting uWSGI |compiled with version: |os: Linux|nodename: |machine: |clock source: |pcre jit |detected number of CPU cores: |current working directory: |writing pidfile to |detected binary path: |chdir.. to |your processes number limit is |your memory page size is |detected max file descriptor number: |lock engine: |thunder lock: |uwsgi socket |setgid.. to |setuid.. to |Python version: |Python main interpreter initialized at |python threads support |your server socket listen backlog is limited to |your mercy for graceful operations on workers is |mapped |... Operational MODE: |... uWSGI is running in multiple interpreter mode ...|spawned uWSGI worker |mounting |WSGI app |announcing my loyalty to the Emperor...|workers have been inactive for more than |SIGINT/SIGQUIT received...killing workers...|worker |goodbye to uWSGI.) +log-route = etebase ^(?!... Starting uWSGI |compiled with version: |os: Linux|nodename: |machine: |clock source: |pcre jit |detected number of CPU cores: |current working directory: |writing pidfile to |detected binary path: |chdir.. to |your processes number limit is |your memory page size is |detected max file descriptor number: |lock engine: |thunder lock: |uwsgi socket |setgid.. to |setuid.. to |Python version: |Python main interpreter initialized at |python threads support |your server socket listen backlog is limited to |your mercy for graceful operations on workers is |mapped |... Operational MODE: |... uWSGI is running in multiple interpreter mode ...|spawned uWSGI worker |mounting |WSGI app |announcing my loyalty to the Emperor...|workers have been inactive for more than |SIGINT/SIGQUIT received...killing workers...|worker |goodbye to uWSGI.) end-if = if-not-env = UWSGI_EMPEROR_FD -log-route = etesync .* +log-route = etebase .* vacuum = true -socket = /var/run/etesync-server.socket +socket = /var/run/etebase.socket end-if = chmod-socket = 660 -chown-socket = etesync:nogroup -uid = etesync +chown-socket = etebase:nogroup +uid = etebase gid = nogroup diff --git a/net/etebase/files/uwsgi.init b/net/etebase/files/uwsgi.init new file mode 100644 index 000000000..516b424f7 --- /dev/null +++ b/net/etebase/files/uwsgi.init @@ -0,0 +1,137 @@ +#!/bin/sh /etc/rc.common + +START=82 + +USE_PROCD=1 + +ETEBASE_INI="/var/etc/etebase/server.ini" + + +etebase_print_uci_allow_all_ips_of() { + local ifstat="$(ifstatus "$1")" + + for ip in $(echo "${ifstat}" | jsonfilter -e '@["ipv4-address"].*.address') + do echo "allowed_host_${ip//[^0-9]/_} = ${ip}" + done + + for ip in $(echo "${ifstat}" | jsonfilter -e '@["ipv6-address"].*.address') + do echo "allowed_host_${ip//[^0-9A-Fa-f]/_} = [${ip}]" + done + + for ip in $(echo "${ifstat}" | \ + jsonfilter -e '@["ipv6-prefix-assignment"].*["local-address"].address') + do echo "allowed_host_${ip//[^0-9A-Fa-f]/_} = [${ip}]" + done +} + + +etebase_validate_global() { + cd /usr/share/etebase/ >/dev/null || return + + uci_load_validate etebase django "global" "$1" \ + 'secret_file:file:secret.txt' \ + 'static_url:string:static/' \ + 'language_code:string:en-us' \ + 'time_zone:string:UTC' \ + 'debug:bool:false' \ + ; +} + + +etebase_print_global() { + printf "\n[global]\n" + + echo "secret_file = ${secret_file}" + echo "static_root = /www/etebase/static" #sic! + echo "static_url = ${static_url}" + echo "language_code = ${language_code}" + echo "time_zone = ${time_zone}" + echo "debug = ${debug}" +} + + +etebase_validate_allowed_hosts() { + cd /usr/share/etebase/ >/dev/null || return + + uci_load_validate etebase django "allowed_hosts" "$1" \ + 'uci_allow_all_ips_of:network' \ + 'allowed_host:host' \ + ; +} + + +etebase_print_allowed_hosts() { + printf "\n[allowed_hosts]\n" + + local iface + for iface in ${uci_allow_all_ips_of} + do etebase_print_uci_allow_all_ips_of "${iface}" + done + + local host + for host in ${allowed_host} + do echo "allowed_host_${host//[^0-9A-Za-z]/_} = ${host}" + done +} + + +etebase_validate_database() { + cd /usr/share/etebase/ >/dev/null || return + + uci_load_validate etebase django "database" "$1" \ + 'engine:hostname:django.db.backends.sqlite3' \ + 'name:file:db.sqlite3' \ + ; +} + + +etebase_print_database() { + printf "\n[database]\n" + echo "engine = ${engine}" + echo "name = ${name}" +} + + +etebase_init() { # This must print ONLY configuration lines: + echo "; This file is re-created from /etc/config/etebase " + etebase_validate_global etebase_print_global + etebase_validate_allowed_hosts etebase_print_allowed_hosts + etebase_validate_database etebase_print_database +} >"${ETEBASE_INI}" + + +start_service() { + mkdir -p /var/etc/etebase/ + + etebase_init + + logger -p 'daemon.info' -t 'etebase_init' 'starting ...' + ln -sf /etc/uwsgi/vassals/etebase.available /var/etc/etebase/uwsgi.ini +} + + +stop_service() { + rm -f /var/etc/etebase/uwsgi.ini "${ETEBASE_INI}" +} + + +reload_service() { + etebase_init + + logger -p 'daemon.info' -t 'etebase_init' 'reloading ...' + kill -SIGHUP "$(cat "/var/etc/etebase/master.pid")" 2>/dev/null + #if the server is in on-demand mode, the ini files are reloaded then, too. +} + + +service_triggers() { + procd_open_validate + etebase_validate_global "$@" + etebase_validate_allowed_hosts "$@" + etebase_validate_database "$@" + procd_close_validate + + config_load etebase + config_list_foreach "allowed_hosts" "uci_allow_all_ips_of" procd_add_reload_interface_trigger + procd_add_reload_trigger etebase +} diff --git a/net/etesync-server/Makefile b/net/etesync-server/Makefile deleted file mode 100644 index ec4a13f57..000000000 --- a/net/etesync-server/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=etesync-server -PKG_VERSION:=0.3.0 -PKG_RELEASE:=3 - -PKG_SOURCE:=etesync-server-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://github.com/etesync/server/archive/v$(PKG_VERSION) -PKG_HASH:=d0728effa898a8b7afb4ce7439e0d0fd46bc819008925f21788d7e113435b579 - -PKG_LICENSE:=AGPL-3.0-only -PKG_LICENSE_FILES:=LICENSE -PKG_MAINTAINER:=Peter Stadler - -PKG_BUILD_PARALLEL:=1 -PYTHON3_PKG_BUILD:=0 - -PKG_UNPACK=$(HOST_TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xzf $(DL_DIR)/$(PKG_SOURCE) - -include $(INCLUDE_DIR)/package.mk -include ../../lang/python/python3-package.mk - - -define Package/etesync-server - SECTION:=net - CATEGORY:=Network - SUBMENU:=Web Servers/Proxies - TITLE:=End-to-End Encrypted Secure Data Sync - URL:=https://www.etesync.com/ - DEPENDS:=+nginx-ssl +python3-light +python3-django \ - +python3-django-restframework +python3-drf-nested-routers \ - +python3-django-cors-headers +python3-django-etesync-journal \ - +uwsgi +uwsgi-python3-plugin +uwsgi-syslog-plugin - USERID:=etesync=44312 -endef - - -define Package/etesync-server/description - End-to-End Encrypted Secure Data Sync -endef - - -Build/Compile:=: - - -define Py3Package/etesync-server/install - $(INSTALL_DIR) $(1)/www/etesync/static/ - - $(INSTALL_DIR) $(1)/etc/uci-defaults/ - $(CP) ./files/81_setup-etesync-server $(1)/etc/uci-defaults/ - - $(INSTALL_DIR) $(1)/etc/nginx/conf.d/ - $(INSTALL_CONF) ./files/etesync.locations $(1)/etc/nginx/conf.d/ - - $(INSTALL_DIR) $(1)/etc/config/ - $(INSTALL_CONF) ./files/uci.cfg $(1)/etc/config/etesync_server - - $(INSTALL_DIR) $(1)/usr/share/etesync-server/templates/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/templates/* \ - $(1)/usr/share/etesync-server/templates/ - - $(INSTALL_DIR) $(1)/usr/share/etesync-server/etesync_server/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/manage.py \ - $(1)/usr/share/etesync-server/ - - $(INSTALL_DATA) $(PKG_BUILD_DIR)/etesync_server/* \ - $(1)/usr/share/etesync-server/etesync_server/ - - $(LN) /var/etc/etesync-server/etesync-server.ini \ - $(1)/usr/share/etesync-server/ - #init creates /var/etc/etesync-server/etesync-server.ini from uci.cfg - - $(INSTALL_DIR) $(1)/etc/uwsgi/vassals/ - $(INSTALL_CONF) ./files/uwsgi.ini \ - $(1)/etc/uwsgi/vassals/etesync-server.available - - $(LN) /var/etc/etesync-server/uwsgi.ini \ - $(1)/etc/uwsgi/vassals/etesync-server.ini - #init links etesync-server.available /var/etc/etesync-server/uwsgi.ini - - $(INSTALL_DIR) $(1)/etc/init.d/ - $(INSTALL_BIN) ./files/uwsgi.init $(1)/etc/init.d/etesync-server -endef - -Py3Package/etesync-server/filespec:= - - -define Package/etesync-server/postrm -#!/bin/sh -[ -n "$${IPKG_INSTROOT}" ] && exit 0 -rmdir --ignore-fail-on-non-empty /usr/share/etesync-server/etesync_server -[ "$${PKG_UPGRADE}" = "1" ] && exit 0 -rm -r /www/etesync/static -rmdir /www/etesync -exit 0 -endef - - -define Package/etesync-server/conffiles -/etc/config/etesync_server -/etc/nginx/conf.d/etesync.locations -/etc/uwsgi/vassals/etesync-server.available -endef - - -$(eval $(call Py3Package,etesync-server)) -$(eval $(call BuildPackage,etesync-server)) -$(eval $(call BuildPackage,etesync-server-src)) diff --git a/net/etesync-server/files/etesync.locations b/net/etesync-server/files/etesync.locations deleted file mode 100644 index 23d9c9f1d..000000000 --- a/net/etesync-server/files/etesync.locations +++ /dev/null @@ -1,13 +0,0 @@ -location /etesync/static { - access_log off; - error_log /dev/null; - expires 1y; - try_files $uri $uri/ =404; -} - -location /etesync { - access_log off; - error_log /dev/null; - include uwsgi_params; - uwsgi_pass unix:///var/run/etesync-server.socket; -} diff --git a/net/etesync-server/files/uwsgi.init b/net/etesync-server/files/uwsgi.init deleted file mode 100644 index a7130883f..000000000 --- a/net/etesync-server/files/uwsgi.init +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=82 - -USE_PROCD=1 - -ETESYNC_INI="/var/etc/etesync-server/etesync-server.ini" - - -etesync_print_uci_allow_all_ips_of() { - local ifstat="$(ifstatus "$1")" - - for ip in $(echo "${ifstat}" | jsonfilter -e '@["ipv4-address"].*.address') - do echo "allowed_host_${ip//[^0-9]/_} = ${ip}" - done - - for ip in $(echo "${ifstat}" | jsonfilter -e '@["ipv6-address"].*.address') - do echo "allowed_host_${ip//[^0-9A-Fa-f]/_} = [${ip}]" - done - - for ip in $(echo "${ifstat}" | \ - jsonfilter -e '@["ipv6-prefix-assignment"].*["local-address"].address') - do echo "allowed_host_${ip//[^0-9A-Fa-f]/_} = [${ip}]" - done -} - - -etesync_validate_global() { - cd /usr/share/etesync-server/ >/dev/null || return - - uci_load_validate etesync_server django "global" "$1" \ - 'secret_file:file:secret.txt' \ - 'static_url:string:/etesync/static' \ - 'language_code:string:en-us' \ - 'time_zone:string:UTC' \ - 'debug:bool:false' \ - ; -} - - -etesync_print_global() { - printf "\n[global]\n" - - echo "secret_file = ${secret_file}" - echo "static_root = /www/etesync/static" #sic! - echo "static_url = ${static_url}" - echo "language_code = ${language_code}" - echo "time_zone = ${time_zone}" - echo "debug = ${debug}" -} - - -etesync_validate_allowed_hosts() { - uci_load_validate etesync_server django "allowed_hosts" "$1" \ - 'uci_allow_all_ips_of:network' \ - 'allowed_host:host' \ - ; -} - - -etesync_print_allowed_hosts() { - printf "\n[allowed_hosts]\n" - - local iface - for iface in ${uci_allow_all_ips_of} - do etesync_print_uci_allow_all_ips_of "${iface}" - done - - local host - for host in ${allowed_host} - do echo "allowed_host_${host//[^0-9A-Za-z]/_} = ${host}" - done -} - - -etesync_validate_database() { - cd /usr/share/etesync-server/ >/dev/null || return - - uci_load_validate etesync_server django "database" "$1" \ - 'engine:hostname:django.db.backends.sqlite3' \ - 'name:file:db.sqlite3' \ - ; -} - - -etesync_print_database() { - printf "\n[database]\n" - - echo "engine = ${engine}" - echo "name = ${name}" -} - - -etesync_init() { # This must print ONLY configuration lines: - echo "; This file is re-created from /etc/config/etesync_server " - etesync_validate_global etesync_print_global - etesync_validate_allowed_hosts etesync_print_allowed_hosts - etesync_validate_database etesync_print_database -} >"${ETESYNC_INI}" - - -start_service() { - mkdir -p /var/etc/etesync-server/ - etesync_init - logger -p 'daemon.info' -t 'etesync-server_init' 'starting ...' - ln -sf /etc/uwsgi/vassals/etesync-server.available \ - /var/etc/etesync-server/uwsgi.ini -} - - -stop_service() { - rm -f /var/etc/etesync-server/uwsgi.ini "${ETESYNC_INI}" -} - - -reload_service() { - etesync_init - logger -p 'daemon.info' -t 'etesync-server_init' 'reloading ...' - kill -SIGHUP "$(cat "/var/etc/etesync-server/master.pid")" 2>/dev/null - #if the server is in on-demand mode, the ini files are reloaded then, too. -} - - -service_triggers() { - procd_open_validate - etesync_validate_global "$@" - etesync_validate_allowed_hosts "$@" - etesync_validate_database "$@" - procd_close_validate - - config_load etesync_server - config_list_foreach "allowed_hosts" "uci_allow_all_ips_of" \ - procd_add_reload_interface_trigger - - procd_add_reload_trigger etesync_server -}