diff options
Diffstat (limited to 'package')
-rw-r--r-- | package/uci/Makefile | 16 | ||||
-rw-r--r-- | package/uci/patches/120-uci_trigger.patch | 168 | ||||
-rwxr-xr-x | package/uci/trigger/apply_config | 54 | ||||
-rw-r--r-- | package/uci/trigger/lib/trigger.lua | 419 | ||||
-rw-r--r-- | package/uci/trigger/modules/base.lua | 63 |
5 files changed, 0 insertions, 720 deletions
diff --git a/package/uci/Makefile b/package/uci/Makefile index ffd37a757b..c29b5ba35d 100644 --- a/package/uci/Makefile +++ b/package/uci/Makefile @@ -41,13 +41,6 @@ define Package/uci TITLE:=Utility for the Unified Configuration Interface (UCI) endef -define Package/ucitrigger - SECTION:=base - CATEGORY:=Base system - DEPENDS:=+libuci-lua +lua - TITLE:=Automatic triggers for applying system config changes -endef - define Package/libuci-lua SECTION=libs CATEGORY=Libraries @@ -72,14 +65,6 @@ define Package/libuci-lua/install $(CP) $(PKG_BUILD_DIR)/lua/uci.so $(1)/usr/lib/lua/ endef -define Package/ucitrigger/install - $(INSTALL_DIR) $(1)/usr/lib/lua/uci $(1)/lib/config/trigger $(1)/usr/sbin - $(INSTALL_DATA) ./trigger/lib/trigger.lua $(1)/usr/lib/lua/uci/ - $(INSTALL_DATA) ./trigger/modules/*.lua $(1)/lib/config/trigger/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/trigger/uci_trigger.so $(1)/usr/lib/ - $(INSTALL_BIN) ./trigger/apply_config $(1)/usr/sbin/ -endef - define Package/uci/install $(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_DIR) $(1)/sbin @@ -98,4 +83,3 @@ endef $(eval $(call BuildPackage,uci)) $(eval $(call BuildPackage,libuci)) $(eval $(call BuildPackage,libuci-lua)) -$(eval $(call BuildPackage,ucitrigger)) diff --git a/package/uci/patches/120-uci_trigger.patch b/package/uci/patches/120-uci_trigger.patch deleted file mode 100644 index 0b63435a7a..0000000000 --- a/package/uci/patches/120-uci_trigger.patch +++ /dev/null @@ -1,168 +0,0 @@ ---- /dev/null -+++ b/trigger/uci_trigger.c -@@ -0,0 +1,132 @@ -+#include <sys/types.h> -+#include <sys/time.h> -+#include <stdbool.h> -+#include <string.h> -+#include <stdio.h> -+#include <lualib.h> -+#include <lauxlib.h> -+#include "uci.h" -+ -+// #define DEBUG -+ -+static int refcount = 0; -+static lua_State *gL = NULL; -+static bool prepared = false; -+ -+struct trigger_set_op { -+ struct uci_package *p; -+ struct uci_delta *h; -+}; -+ -+static int trigger_set(lua_State *L) -+{ -+ struct trigger_set_op *so = -+ (struct trigger_set_op *)lua_touserdata(L, 1); -+ struct uci_package *p = so->p; -+ struct uci_delta *h = so->h; -+ struct uci_context *ctx = p->ctx; -+ -+ /* ignore non-standard savedirs/configdirs -+ * in order to not trigger events on uci state changes */ -+ if (strcmp(ctx->savedir, UCI_SAVEDIR) || -+ strcmp(ctx->confdir, UCI_CONFDIR)) -+ return 0; -+ -+ if (!prepared) { -+ lua_getglobal(L, "require"); -+ lua_pushstring(L, "uci.trigger"); -+ lua_call(L, 1, 0); -+ -+ lua_getglobal(L, "uci"); -+ lua_getfield(L, -1, "trigger"); -+ lua_getfield(L, -1, "load_modules"); -+ lua_call(L, 0, 0); -+ prepared = true; -+ } else { -+ lua_getglobal(L, "uci"); -+ lua_getfield(L, -1, "trigger"); -+ } -+ -+ lua_getfield(L, -1, "set"); -+ lua_createtable(L, 4, 0); -+ -+ lua_pushstring(L, p->e.name); -+ lua_rawseti(L, -2, 1); -+ if (h->section) { -+ lua_pushstring(L, h->section); -+ lua_rawseti(L, -2, 2); -+ } -+ if (h->e.name) { -+ lua_pushstring(L, h->e.name); -+ lua_rawseti(L, -2, 3); -+ } -+ if (h->value) { -+ lua_pushstring(L, h->value); -+ lua_rawseti(L, -2, 4); -+ } -+ lua_call(L, 1, 0); -+ lua_pop(L, 2); -+ return 0; -+} -+ -+#ifdef DEBUG -+ -+static int report (lua_State *L, int status) { -+ if (status && !lua_isnil(L, -1)) { -+ const char *msg = lua_tostring(L, -1); -+ if (msg == NULL) msg = "(error object is not a string)"; -+ fprintf(stderr, "ERROR: %s\n", msg); -+ lua_pop(L, 1); -+ } -+ return status; -+} -+ -+#else -+ -+static inline int report(lua_State *L, int status) { -+ return status; -+} -+ -+#endif -+ -+static void trigger_set_hook(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_delta *h) -+{ -+ struct trigger_set_op so; -+ -+ so.p = p; -+ so.h = h; -+ report(gL, lua_cpcall(gL, &trigger_set, &so)); -+} -+ -+static struct uci_hook_ops hook = { -+ .set = trigger_set_hook, -+}; -+ -+static int trigger_attach(struct uci_context *ctx) -+{ -+ if (!gL) { -+ gL = luaL_newstate(); -+ if (!gL) -+ return -1; -+ luaL_openlibs(gL); -+ -+ refcount++; -+ } -+ uci_add_hook(ctx, &hook); -+ return 0; -+} -+ -+static void trigger_detach(struct uci_context *ctx) -+{ -+ if (gL && (--refcount <= 0)) { -+ lua_close(gL); -+ gL = NULL; -+ refcount = 0; -+ prepared = false; -+ } -+} -+ -+struct uci_plugin_ops uci_plugin = { -+ .attach = trigger_attach, -+ .detach = trigger_detach, -+}; ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -35,6 +35,7 @@ ADD_EXECUTABLE(ucimap-example ucimap-exa - TARGET_LINK_LIBRARIES(ucimap-example uci-static ucimap dl) - - ADD_SUBDIRECTORY(lua) -+ADD_SUBDIRECTORY(trigger) - - INSTALL(FILES uci.h uci_config.h ucimap.h - DESTINATION include/libubox ---- /dev/null -+++ b/trigger/CMakeLists.txt -@@ -0,0 +1,19 @@ -+cmake_minimum_required(VERSION 2.6) -+ -+PROJECT(uci C) -+ -+SET(CMAKE_INSTALL_PREFIX /) -+ -+ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -I..) -+ -+IF(APPLE) -+ SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -undefined dynamic_lookup") -+ENDIF(APPLE) -+ -+ADD_LIBRARY(uci_trigger MODULE uci_trigger.c) -+SET_TARGET_PROPERTIES(uci_trigger PROPERTIES -+ OUTPUT_NAME uci_trigger -+ PREFIX "" -+) -+TARGET_LINK_LIBRARIES(uci_trigger uci) -+ - diff --git a/package/uci/trigger/apply_config b/package/uci/trigger/apply_config deleted file mode 100755 index 2ad6c9992a..0000000000 --- a/package/uci/trigger/apply_config +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/lua -require("uci") -require("uci.trigger") - -function usage() - print("Usage: " .. arg[0] .. " [options]") - print("Options:") - print(" -a: apply the config changes") - print(" -t: show matching UCI triggers") - print(" -s: show information about tasks to be executed") - print(" -r: reset all triggers") - print(" -C <trigger> [<section>]: force clear a trigger") - print(" -S <trigger> [<section>]: force set a trigger") - print("") -end - -if arg[1] == "-s" then - local triggers = uci.trigger.get_active() - if #triggers > 0 then - print("Tasks:") - for i, a in ipairs(triggers) do - local trigger = a[1] - local sections = a[2] - print(" - " .. uci.trigger.get_description(trigger, sections)) - end - else - print "Nothing to do" - end -elseif arg[1] == "-t" then - local triggers = uci.trigger.get_active() - for i, a in ipairs(triggers) do - local trigger = a[1] - local sections = a[2] - if trigger.section_only then - print(trigger.id .. " " .. table.concat(sections, " ")) - else - print(trigger.id) - end - end -elseif arg[1] == "-a" then - uci.trigger.run() -elseif arg[1] == "-r" then - uci.trigger.reset_state() -elseif arg[1] == "-S" then - local trigger = arg[2] - local section = arg[3] - uci.trigger.set_active(trigger, section) -elseif arg[1] == "-C" then - local trigger = arg[2] - local section = arg[3] - uci.trigger.clear_active(trigger, section) -else - usage() -end diff --git a/package/uci/trigger/lib/trigger.lua b/package/uci/trigger/lib/trigger.lua deleted file mode 100644 index 104d27ae44..0000000000 --- a/package/uci/trigger/lib/trigger.lua +++ /dev/null @@ -1,419 +0,0 @@ -module("uci.trigger", package.seeall) -require("posix") -require("uci") - -local path = "/lib/config/trigger" -local triggers = nil -local tmp_cursor = nil - -function load_modules() - if triggers ~= nil then - return - end - triggers = { - list = {}, - uci = {}, - active = {} - } - local modules = posix.glob(path .. "/*.lua") - if modules == nil then - return - end - local oldpath = package.path - package.path = path .. "/?.lua" - for i, v in ipairs(modules) do - pcall(require(string.gsub(v, path .. "/(%w+)%.lua$", "%1"))) - end - package.path = oldpath -end - -function check_table(table, name) - if table[name] == nil then - table[name] = {} - end - return table[name] -end - -function get_table_val(val, vtype) - if type(val) == (vtype or "string") then - return { val } - elseif type(val) == "table" then - return val - end - return nil -end - -function get_name_list(name) - return get_table_val(name or ".all") -end - -function add_trigger_option(list, t) - local name = get_name_list(t.option) - for i, n in ipairs(name) do - option = check_table(list, n) - table.insert(option, t) - end -end - -function add_trigger_section(list, t) - local name = get_name_list(t.section) - for i, n in ipairs(name) do - section = check_table(list, n) - add_trigger_option(section, t) - end -end - -function check_insert_triggers(dest, list, tuple) - if list == nil then - return - end - for i, t in ipairs(list) do - local add = true - if type(t.check) == "function" then - add = t.check(tuple) - end - if add then - dest[t.id] = t - end - end -end - -function find_section_triggers(tlist, pos, tuple) - if pos == nil then - return - end - check_insert_triggers(tlist, pos[".all"], tuple) - if tuple.option then - check_insert_triggers(tlist, pos[tuple.option], tuple) - end -end - -function check_recursion(name, seen) - if seen == nil then - seen = {} - end - if seen[name] then - return nil - end - seen[name] = true - return seen -end - - -function find_recursive_depends(list, name, seen) - seen = check_recursion(name, seen) - if not seen then - return - end - local bt = get_table_val(triggers.list[name].belongs_to) or {} - for i, n in ipairs(bt) do - table.insert(list, n) - find_recursive_depends(list, n, seen) - end -end - -function check_trigger_depth(list, name) - if name == nil then - return - end - - local n = list[name] - if n == nil then - return - end - - list[name] = nil - return check_trigger_depth(list, n) -end - -function find_triggers(tuple) - local pos = triggers.uci[tuple.package] - if pos == nil then - return {} - end - - local tlist = {} - find_section_triggers(tlist, pos[".all"], tuple) - find_section_triggers(tlist, pos[tuple.section[".type"]], tuple) - - for n, t in pairs(tlist) do - local dep = {} - find_recursive_depends(dep, t.id) - for i, depname in ipairs(dep) do - check_trigger_depth(tlist, depname) - end - end - - local nlist = {} - for n, t in pairs(tlist) do - if t then - table.insert(nlist, t) - end - end - - return nlist -end - -function reset_state() - assert(io.open("/var/run/uci_trigger", "w")):close() - if tctx then - tctx:unload("uci_trigger") - end -end - -function load_state() - -- make sure the config file exists before we attempt to load it - -- uci doesn't like loading nonexistent config files - local f = assert(io.open("/var/run/uci_trigger", "a")):close() - - load_modules() - triggers.active = {} - if tctx then - tctx:unload("uci_trigger") - else - tctx = uci.cursor() - end - assert(tctx:load("/var/run/uci_trigger")) - tctx:foreach("uci_trigger", "trigger", - function(section) - trigger = triggers.list[section[".name"]] - if trigger == nil then - return - end - - active = {} - triggers.active[trigger.id] = active - - local s = get_table_val(section["sections"]) or {} - for i, v in ipairs(s) do - active[v] = true - end - end - ) -end - -function get_names(list) - local slist = {} - for name, val in pairs(list) do - if val then - table.insert(slist, name) - end - end - return slist -end - -function check_cancel(name, seen) - local t = triggers.list[name] - local dep = get_table_val(t.belongs_to) - seen = check_recursion(name, seen) - - if not t or not dep or not seen then - return false - end - - for i, v in ipairs(dep) do - -- only cancel triggers for all sections - -- if both the current and the parent trigger - -- are per-section - local section_only = false - if t.section_only then - local tdep = triggers.list[v] - if tdep then - section_only = tdep.section_only - end - end - - if check_cancel(v, seen) then - return true - end - if triggers.active[v] then - if section_only then - for n, active in pairs(triggers.active[v]) do - triggers.active[name][n] = false - end - else - return true - end - end - end - return false -end - --- trigger api functions - -function add(ts) - for i,t in ipairs(ts) do - triggers.list[t.id] = t - match = {} - if t.package then - local package = check_table(triggers.uci, t.package) - add_trigger_section(package, t) - triggers.list[t.id] = t - end - end -end - -function save_trigger(name) - if triggers.active[name] then - local slist = get_names(triggers.active[name]) - if #slist > 0 then - tctx:set("uci_trigger", name, "sections", slist) - end - else - tctx:delete("uci_trigger", name) - end -end - -function set(data, cursor) - assert(data ~= nil) - if cursor == nil then - cursor = tmp_cursor or uci.cursor() - tmp_cursor = uci.cursor - end - - local tuple = { - package = data[1], - section = data[2], - option = data[3], - value = data[4] - } - assert(cursor:load(tuple.package)) - - load_state() - local section = cursor:get_all(tuple.package, tuple.section) - if (section == nil) then - if option ~= nil then - return - end - section = { - [".type"] = value - } - if tuple.section == nil then - tuple.section = "" - section[".anonymous"] = true - end - section[".name"] = tuple.section - end - tuple.section = section - - local ts = find_triggers(tuple) - for i, t in ipairs(ts) do - local active = triggers.active[t.id] - if not active then - active = {} - triggers.active[t.id] = active - tctx:set("uci_trigger", t.id, "trigger") - end - if section[".name"] then - active[section[".name"]] = true - end - save_trigger(t.id) - end - tctx:save("uci_trigger") -end - -function get_description(trigger, sections) - if not trigger.title then - return trigger.id - end - local desc = trigger.title - if trigger.section_only and sections and #sections > 0 then - desc = desc .. " (" .. table.concat(sections, ", ") .. ")" - end - return desc -end - -function get_active() - local slist = {} - - if triggers == nil then - load_state() - end - for name, val in pairs(triggers.active) do - if val and not check_cancel(name) then - local sections = {} - for name, active in pairs(triggers.active[name]) do - if active then - table.insert(sections, name) - end - end - table.insert(slist, { triggers.list[name], sections }) - end - end - return slist -end - -function set_active(trigger, sections) - if triggers == nil then - load_state() - end - if not triggers.list[trigger] then - return - end - if triggers.active[trigger] == nil then - tctx:set("uci_trigger", trigger, "trigger") - triggers.active[trigger] = {} - end - local active = triggers.active[trigger] - if triggers.list[trigger].section_only or sections ~= nil then - for i, t in ipairs(sections) do - triggers.active[trigger][t] = true - end - end - save_trigger(trigger) - tctx:save("uci_trigger") -end - -function clear_active(trigger, sections) - if triggers == nil then - load_state() - end - if triggers.list[trigger] == nil or triggers.active[trigger] == nil then - return - end - local active = triggers.active[trigger] - if not triggers.list[trigger].section_only or sections == nil then - triggers.active[trigger] = nil - else - for i, t in ipairs(sections) do - triggers.active[trigger][t] = false - end - end - save_trigger(trigger) - tctx:save("uci_trigger") -end - -function run(ts) - if ts == nil then - ts = get_active() - end - for i, t in ipairs(ts) do - local trigger = t[1] - local sections = t[2] - local actions = get_table_val(trigger.action, "function") or {} - for ai, a in ipairs(actions) do - if not trigger.section_only then - sections = { "" } - end - for si, s in ipairs(sections) do - if a(s) then - tctx:delete("uci_trigger", trigger.id) - tctx:save("uci_trigger") - end - end - end - end -end - --- helper functions - -function system_command(arg) - local cmd = arg - return function(arg) - return os.execute(cmd:format(arg)) == 0 - end -end - -function service_restart(arg) - return system_command("/etc/init.d/" .. arg .. " restart") -end diff --git a/package/uci/trigger/modules/base.lua b/package/uci/trigger/modules/base.lua deleted file mode 100644 index 3ab6bba652..0000000000 --- a/package/uci/trigger/modules/base.lua +++ /dev/null @@ -1,63 +0,0 @@ -module("trigger.base", package.seeall) -require("uci.trigger") - -uci.trigger.add { - { - id = "dnsmasq_restart", - title = "Restart dnsmasq", - package = "dhcp", - action = uci.trigger.service_restart("dnsmasq"), - }, - { - id = "dropbear_restart", - title = "Restart dropbear", - package = "dropbear", - action = uci.trigger.service_restart("dropbear"), - }, - { - id = "fstab_restart", - title = "Remount filesystems", - package = "fstab", - action = uci.trigger.service_restart("fstab"), - }, - { - id = "firewall_restart", - title = "Reload firewall rules", - package = "firewall", - action = uci.trigger.service_restart("firewall"), - }, - { - id = "httpd_restart", - title = "Restart the http server", - package = "httpd", - action = uci.trigger.service_restart("httpd") - }, - { - id = "led_restart", - title = "Reload LED settings", - package = "system", - section = "led", - action = uci.trigger.service_restart("led") - }, - { - id = "network_restart", - title = "Restart networking and wireless", - package = "network", - action = uci.trigger.service_restart("network") - }, - { - id = "qos_restart", - title = "Reload Quality of Service rules", - package = "qos", - action = uci.trigger.service_restart("qos"), - }, - { - id = "wireless_restart", - title = "Restart all wireless interfaces", - package = "wireless", - section = { "wifi-device", "wifi-iface" }, - action = uci.trigger.system_command("wifi"), - belongs_to = "network_restart" - }, -} - |