#!/opt/lnxall_app/bin/lua -- Created by jiaqiang.ye@lnxall.com -- Simple `/lib/dyiot/initd/XXX script -- 2023/04/13 -- load external modules local ubus = require "ubus" local cjson = require "cjson" local posix = require "posix" local uloop = require "uloop" local PATHSTR = '/opt/lnxall_app/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin' -- global variables local g_ucon = nil -- ubus connection handle local g_appname = nil -- application name local function badstr(s) if type(s) ~= "string" then return true end if string.len(s) == 0 then return true end return false end local function print_help() io.stderr:write([[ Syntax: /lib/dyiot/initd/XXX [command] Available commands: start Start the service stop Stop the service restart Restart the service reload Reload configuration files (actuall identical to restart) enable Enable service autostart disable Disable service autostart status Service status addfile Load seperate application from JSON file delfile Stop and delete application from JSON file ]]) io.stderr:flush() end local function initd_prepare(apppath, arg1) uloop.init() -- initialize uloop first -- setup PATH environment variable if posix.setenv('PATH', PATHSTR, 1) ~= 0 then io.stderr:write("Error, failed to setup PATH environment variable!\n") io.stderr:flush() return false end if badstr(apppath) then io.stderr:write("Error, cannot determine application name.\n") io.stderr:flush() return false end local appn = string.match(apppath, "/([^/]+)$") if not appn or string.len(appn) == 0 then appn = apppath end g_appname = appn if appn == "initd.lua" then if badstr(arg1) then io.stderr:write("Error, application name not specified.\n") print_help() return false end g_appname = arg1 table.remove(arg, 1) end -- connect to ubus daemon g_ucon = ubus.connect(nil, 2) -- timeout in 2 seconds if not g_ucon then io.stderr:write("Error, failed to connect to ubus daemon!\n") io.stderr:flush() return false end return true end local function process_action(action, filepath) local appn = g_appname local reply, eval = g_ucon:call('initd', string.format("app_%s", action), { ["appname"] = appn, ["filepath"] = filepath }) if not reply then if type(eval) ~= "string" then eval = tostring(eval) end io.stderr:write(string.format("%s %s has failed: %s\n", appn, action, eval)) io.stderr:flush() return 1 end if type(reply) == "table" then reply = cjson.encode(reply) end if type(reply) == "string" then io.stdout:write(string.format("%s %s => %s\n", appn, action, reply)) io.stdout:flush() end return 0 end local function iter_args(args) local rval = 0 local argc, done = 0, 0 while true do argc = argc + 0x1 local argn, argm = args[argc], nil if badstr(argn) then break end if argn == "addfile" or argn == "delfile" then argc = argc + 0x1 argm = args[argc] if badstr(argm) then io.stderr:write(string.format("Error, json-file not specified for %s\n", argn)) io.stderr:flush() os.exit(2) end end done = done + 0x1 rval = rval + process_action(argn, argm) end if done == 0 then print_help() os.exit(1) end os.exit(rval) end if initd_prepare(arg[0], arg[1]) then iter_args(arg) end os.exit(2)