v1.3. Refactoring. internet-detector-mod-modem-restart, internet-detector-mod-email

This commit is contained in:
gSpot
2024-02-19 17:50:33 +03:00
parent b5a4429854
commit 3f245bb410
24 changed files with 1300 additions and 1010 deletions

View File

@@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector
PKG_VERSION:=1.2
PKG_VERSION:=1.3
PKG_RELEASE:=0
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
@@ -50,14 +50,13 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) ./files/etc/init.d/internet-detector $(1)/etc/init.d/internet-detector
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/usr/bin/internet-detector $(1)/usr/bin/internet-detector
$(INSTALL_DIR) $(1)/usr/lib/internet-detector
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_email.lua $(1)/usr/lib/internet-detector/mod_email.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_public_ip.lua $(1)/usr/lib/internet-detector/mod_public_ip.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_led_control.lua $(1)/usr/lib/internet-detector/mod_led_control.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_modem_restart.lua $(1)/usr/lib/internet-detector/mod_modem_restart.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_network_restart.lua $(1)/usr/lib/internet-detector/mod_network_restart.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_reboot.lua $(1)/usr/lib/internet-detector/mod_reboot.lua
$(INSTALL_DATA) ./files/usr/lib/internet-detector/mod_user_scripts.lua $(1)/usr/lib/internet-detector/mod_user_scripts.lua
$(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/main.lua $(1)/usr/lib/lua/internet-detector/main.lua
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/mod_led_control.lua $(1)/usr/lib/lua/internet-detector/mod_led_control.lua
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/mod_reboot.lua $(1)/usr/lib/lua/internet-detector/mod_reboot.lua
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/mod_network_restart.lua $(1)/usr/lib/lua/internet-detector/mod_network_restart.lua
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/mod_public_ip.lua $(1)/usr/lib/lua/internet-detector/mod_public_ip.lua
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/mod_user_scripts.lua $(1)/usr/lib/lua/internet-detector/mod_user_scripts.lua
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,3 +1,4 @@
config main 'config'
option mode '1'
option enable_logger '1'
@@ -12,7 +13,6 @@ config instance 'internet'
option interval_down '5'
option connection_attempts '2'
option connection_timeout '2'
option mod_led_control_enabled '0'
option mod_reboot_enabled '0'
option mod_reboot_dead_period '3600'
option mod_reboot_force_reboot_delay '300'
@@ -30,9 +30,8 @@ config instance 'internet'
option mod_public_ip_timeout '3'
option mod_public_ip_enable_ip_script '0'
option mod_email_enabled '0'
option mod_email_mode '0'
option mod_email_alive_period '0'
option mod_email_mail_smtp 'smtp.gmail.com'
option mod_email_mail_smtp_port '587'
option mod_email_mail_security 'tls'
option mod_user_scripts_enabled '0'
option mod_user_scripts_alive_period '0'

View File

@@ -11,633 +11,7 @@
(с) 2024 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector)
--]]
-- Importing packages
local dirent = require("posix.dirent")
local fcntl = require("posix.fcntl")
local signal = require("posix.signal")
local socket = require("posix.sys.socket")
local stat = require("posix.sys.stat")
local syslog = require("posix.syslog")
local time = require("posix.time")
local unistd = require("posix.unistd")
local uci = require("uci")
-- Default settings
local InternetDetector = {
mode = 0, -- 0: disabled, 1: Service, 2: UI detector
enableLogger = true,
hostname = "OpenWrt",
appName = "internet-detector",
commonDir = "/tmp/run",
pingCmd = "/bin/ping",
pingParams = "-c 1",
uiRunTime = 30,
noModules = false,
uiAvailModules = { mod_public_ip = true },
debug = false,
serviceConfig = {
hosts = {
[1] = "8.8.8.8",
[2] = "1.1.1.1",
},
check_type = 0, -- 0: TCP, 1: ICMP
tcp_port = 53,
icmp_packet_size = 56,
interval_up = 30,
interval_down = 5,
connection_attempts = 2,
connection_timeout = 2,
iface = nil,
instance = nil,
},
modules = {},
parsedHosts = {},
uiCounter = 0,
}
InternetDetector.configDir = string.format("/etc/%s", InternetDetector.appName)
InternetDetector.modulesDir = string.format("/usr/lib/%s", InternetDetector.appName)
-- Loading settings from UCI
local uciCursor = uci.cursor()
InternetDetector.mode = tonumber(
uciCursor:get(InternetDetector.appName, "config", "mode"))
InternetDetector.enableLogger = (tonumber(
uciCursor:get(InternetDetector.appName, "config", "enable_logger")) ~= 0)
local hostname = uciCursor:get("system", "@[0]", "hostname")
if hostname ~= nil then
InternetDetector.hostname = hostname
end
local RUNNING
function InternetDetector:prequire(package)
local retVal, pkg = pcall(require, package)
return retVal and pkg
end
function InternetDetector:loadUCIConfig(sType, instance)
local success
local num = 0
uciCursor:foreach(
self.appName,
sType,
function(s)
if s[".name"] == instance then
for k, v in pairs(s) do
if type(v) == "string" and v:match("^[%d]+$") then
v = tonumber(v)
end
self.serviceConfig[k] = v
end
success = true
self.serviceConfig.instanceNum = num
end
num = num + 1
end
)
self.serviceConfig.instance = instance
self.pidFile = string.format(
"%s/%s.%s.pid", self.commonDir, self.appName, instance)
self.statusFile = string.format(
"%s/%s.%s.status", self.commonDir, self.appName, instance)
return success
end
function InternetDetector:writeValueToFile(filePath, str)
local retValue = false
local fh = io.open(filePath, "w")
if fh then
fh:setvbuf("no")
fh:write(string.format("%s\n", str))
fh:close()
retValue = true
end
return retValue
end
function InternetDetector:readValueFromFile(filePath)
local retValue
local fh = io.open(filePath, "r")
if fh then
retValue = fh:read("*l")
fh:close()
end
return retValue
end
function InternetDetector:statusJson(inet, instance, t)
local lines = { [1] = string.format(
'{"instance":"%s","num":"%d","inet":%d',
instance,
self.serviceConfig.instanceNum,
inet)}
if t then
for k, v in pairs(t) do
lines[#lines + 1] = string.format('"%s":"%s"', k, v)
end
end
return table.concat(lines, ",") .. "}"
end
function InternetDetector:writeLogMessage(level, msg)
if self.enableLogger then
local levels = {
emerg = syslog.LOG_EMERG,
alert = syslog.LOG_ALERT,
crit = syslog.LOG_CRIT,
err = syslog.LOG_ERR,
warning = syslog.LOG_WARNING,
notice = syslog.LOG_NOTICE,
info = syslog.LOG_INFO,
debug = syslog.LOG_DEBUG,
}
syslog.syslog(levels[level] or syslog.LOG_INFO, string.format(
"%s: %s", self.serviceConfig.instance or "", msg))
end
end
function InternetDetector:loadModules()
package.path = string.format("%s;%s/?.lua", package.path, self.modulesDir)
self.modules = {}
local ok, modulesDir = pcall(dirent.files, self.modulesDir)
if ok then
for item in modulesDir do
if item:match("^mod_") then
local modName = item:gsub("%.lua$", "")
if self.noModules and not self.uiAvailModules[modName] then
else
local modConfig = {}
for k, v in pairs(self.serviceConfig) do
if k:match("^" .. modName) then
modConfig[k:gsub("^" .. modName .. "_", "")] = v
end
end
if modConfig.enabled == 1 then
local m = self:prequire(modName)
if m then
m.config = self
m.syslog = function(level, msg) self:writeLogMessage(level, msg) end
m.writeValue = function(filePath, str) return self:writeValueToFile(filePath, str) end
m.readValue = function(filePath) return self:readValueFromFile(filePath) end
m:init(modConfig)
self.modules[#self.modules + 1] = m
end
end
end
end
end
table.sort(self.modules, function(a, b) return a.runPrio < b.runPrio end)
end
end
function InternetDetector:parseHost(host)
local addr, port = host:match("^([^%[%]:]+):?(%d?%d?%d?%d?%d?)$")
if not addr then
addr, port = host:match("^%[?([^%[%]]+)%]?:?(%d?%d?%d?%d?%d?)$")
end
return addr, tonumber(port)
end
function InternetDetector:parseHosts()
self.parsedHosts = {}
for k, v in ipairs(self.serviceConfig.hosts) do
local addr, port = self:parseHost(v)
self.parsedHosts[k] = { addr = addr, port = port }
end
end
function InternetDetector:pingHost(host)
local ping = string.format(
"%s %s -W %d -s %d%s %s > /dev/null 2>&1",
self.pingCmd,
self.pingParams,
self.serviceConfig.connection_timeout,
self.serviceConfig.icmp_packet_size,
self.serviceConfig.iface and (" -I " .. self.serviceConfig.iface) or "",
host
)
local retCode = os.execute(ping)
if self.debug then
io.stdout:write(string.format(
"--- Ping ---\ntime = %s\n%s\nretCode = %s\n", os.time(), ping, retCode)
)
io.stdout:flush()
end
return retCode
end
function InternetDetector:TCPConnectionToHost(host, port)
local retCode = 1
local saTable, errMsg, errNum = socket.getaddrinfo(host, port or self.serviceConfig.tcp_port)
if not saTable then
if self.debug then
io.stdout:write(string.format(
"GETADDRINFO ERROR: %s, %s\n", errMsg, errNum))
end
else
local family = saTable[1].family
if family then
local sock, errMsg, errNum = socket.socket(family, socket.SOCK_STREAM, 0)
if not sock then
if self.debug then
io.stdout:write(string.format(
"SOCKET ERROR: %s, %s\n", errMsg, errNum))
end
return retCode
end
socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_SNDTIMEO, self.serviceConfig.connection_timeout, 0)
socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_RCVTIMEO, self.serviceConfig.connection_timeout, 0)
if self.serviceConfig.iface then
local ok, errMsg, errNum = socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_BINDTODEVICE, self.serviceConfig.iface)
if not ok then
if self.debug then
io.stdout:write(string.format(
"SOCKET ERROR: %s, %s\n", errMsg, errNum))
end
unistd.close(sock)
return retCode
end
end
local success = socket.connect(sock, saTable[1])
if self.debug then
if not success then
io.stdout:write(string.format(
"SOCKET CONNECT ERROR: %s\n", tostring(success)))
end
local sockTable, err_s, e_s = socket.getsockname(sock)
local peerTable, err_p, e_p = socket.getpeername(sock)
if not sockTable then
sockTable = {}
io.stdout:write(
string.format("SOCKET ERROR: %s, %s\n", err_s, e_s))
end
if not peerTable then
peerTable = {}
io.stdout:write(
string.format("SOCKET ERROR: %s, %s\n", err_p, e_p))
end
io.stdout:write(string.format(
"--- TCP ---\ntime = %s\nconnection_timeout = %s\niface = %s\nhost:port = [%s]:%s\nsockname = [%s]:%s\npeername = [%s]:%s\nsuccess = %s\n",
os.time(),
self.serviceConfig.connection_timeout,
tostring(self.serviceConfig.iface),
host,
port or self.serviceConfig.tcp_port,
tostring(sockTable.addr),
tostring(sockTable.port),
tostring(peerTable.addr),
tostring(peerTable.port),
tostring(success))
)
io.stdout:flush()
end
socket.shutdown(sock, socket.SHUT_RDWR)
unistd.close(sock)
retCode = success and 0 or 1
end
end
return retCode
end
function InternetDetector:checkHosts()
local checkFunc = (self.serviceConfig.check_type == 1) and self.pingHost or self.TCPConnectionToHost
local retCode = 1
for k, v in ipairs(self.parsedHosts) do
for i = 1, self.serviceConfig.connection_attempts do
if checkFunc(self, v.addr, v.port) == 0 then
retCode = 0
break
end
end
if retCode == 0 then
break
end
end
return retCode
end
function InternetDetector:breakMain(signo)
RUNNING = false
end
function InternetDetector:resetUiCounter(signo)
self.uiCounter = 0
end
function InternetDetector:main()
signal.signal(signal.SIGTERM, function(signo) self:breakMain(signo) end)
signal.signal(signal.SIGINT, function(signo) self:breakMain(signo) end)
signal.signal(signal.SIGQUIT, function(signo) self:breakMain(signo) end)
signal.signal(signal.SIGUSR1, function(signo) self:resetUiCounter(signo) end)
local lastStatus, currentStatus, mTimeNow, mTimeDiff, mLastTime, uiTimeNow, uiLastTime
local interval = self.serviceConfig.interval_up
local counter = 0
local onStart = true
RUNNING = true
while RUNNING do
if counter == 0 or counter >= interval then
currentStatus = self:checkHosts()
if onStart or not stat.stat(self.statusFile) then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
onStart = false
end
if currentStatus == 0 then
interval = self.serviceConfig.interval_up
if lastStatus ~= nil and currentStatus ~= lastStatus then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
self:writeLogMessage("notice", "Connected")
end
else
interval = self.serviceConfig.interval_down
if lastStatus ~= nil and currentStatus ~= lastStatus then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
self:writeLogMessage("notice", "Disconnected")
end
end
counter = 0
end
mTimeDiff = 0
for _, e in ipairs(self.modules) do
mTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec
if mLastTime then
mTimeDiff = mTimeDiff + mTimeNow - mLastTime
else
mTimeDiff = 1
end
mLastTime = mTimeNow
e:run(currentStatus, lastStatus, mTimeDiff)
end
local modulesStatus = {}
for k, v in ipairs(self.modules) do
if v.status ~= nil then
modulesStatus[v.name] = v.status
end
end
if next(modulesStatus) then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance, modulesStatus))
end
lastStatus = currentStatus
unistd.sleep(1)
counter = counter + 1
if self.mode == 2 then
uiTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec
if uiLastTime then
self.uiCounter = self.uiCounter + uiTimeNow - uiLastTime
else
self.uiCounter = self.uiCounter + 1
end
uiLastTime = uiTimeNow
if self.uiCounter >= self.uiRunTime then
self:breakMain(signal.SIGTERM)
end
end
end
end
function InternetDetector:removeProcessFiles()
os.remove(string.format(
"%s/%s.%s.pid", self.commonDir, self.appName, self.serviceConfig.instance))
os.remove(string.format(
"%s/%s.%s.status", self.commonDir, self.appName, self.serviceConfig.instance))
end
function InternetDetector:status()
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
local appName = self.appName:gsub("-", "%%-")
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
return "running"
end
end
end
return "stoped"
end
function InternetDetector:inetStatus()
local inetStat = '{"instances":[]}'
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
local appName = self.appName:gsub("-", "%%-")
local lines = {}
for item in commonDir do
if item:match("^" .. appName .. ".-%.status$") then
lines[#lines + 1] = self:readValueFromFile(
string.format("%s/%s", self.commonDir, item))
end
end
inetStat = '{"instances":[' .. table.concat(lines, ",") .. "]}"
end
return inetStat
end
function InternetDetector:stopInstance(pidFile)
local retVal
if stat.stat(pidFile) then
pidValue = self:readValueFromFile(pidFile)
if pidValue then
local ok, errMsg, errNum
for i = 0, 10 do
ok, errMsg, errNum = signal.kill(tonumber(pidValue), signal.SIGTERM)
if ok then
break
end
end
if not ok then
io.stderr:write(string.format(
'Process stop error: %s (%s). PID: "%s"\n', errMsg, errNum, pidValue))
end
if errNum == 3 then
os.remove(pidFile)
end
retVal = true
end
end
if not pidValue then
io.stderr:write(
string.format('PID file "%s" does not exist. %s not running?\n',
pidFile, self.appName))
end
return retVal
end
function InternetDetector:stop()
local appName = self.appName:gsub("-", "%%-")
local success
for i = 0, 10 do
success = true
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
self:stopInstance(string.format("%s/%s", self.commonDir, item))
success = false
end
end
if success then
break
end
unistd.sleep(1)
else
break
end
end
end
function InternetDetector:setSIGUSR()
local appName = self.appName:gsub("-", "%%-")
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
pidValue = self:readValueFromFile(string.format("%s/%s", self.commonDir, item))
if pidValue then
signal.kill(tonumber(pidValue), signal.SIGUSR1)
end
end
end
end
end
function InternetDetector:preRun()
-- Exit if internet-detector mode != (1 or 2)
if self.mode ~= 1 and self.mode ~= 2 then
io.stderr:write(string.format('Start failed, mode != (1 or 2)\n', self.appName))
os.exit(0)
end
if stat.stat(self.pidFile) then
io.stderr:write(
string.format('PID file "%s" already exist. %s already running?\n',
self.pidFile, self.appName))
return false
end
return true
end
function InternetDetector:run()
local pidValue = unistd.getpid()
self:writeValueToFile(self.pidFile, pidValue)
if self.enableLogger then
syslog.openlog(self.appName, syslog.LOG_PID, syslog.LOG_DAEMON)
end
self:writeLogMessage("info", "started")
self:loadModules()
-- Loaded modules
local modules = {}
for _, v in ipairs(self.modules) do
modules[#modules + 1] = string.format("%s", v.name)
end
if #modules > 0 then
self:writeLogMessage(
"info", string.format("Loaded modules: %s", table.concat(modules, ", "))
)
end
if self.debug then
local function inspectTable()
local tables = {}, f
f = function(t, prefix)
tables[t] = true
for k, v in pairs(t) do
io.stdout:write(string.format(
"%s%s = %s\n", prefix, k, tostring(v))
)
if type(v) == "table" and not tables[v] then
f(v, string.format("%s%s.", prefix, k))
end
end
end
return f
end
io.stdout:write("--- Config ---\n")
inspectTable()(self, "self.")
io.stdout:flush()
end
self:writeValueToFile(
self.statusFile, self:statusJson(-1, self.serviceConfig.instance))
self:main()
self:removeProcessFiles()
if self.enableLogger then
self:writeLogMessage("info", "stoped")
syslog.closelog()
end
end
function InternetDetector:noDaemon()
if not self:preRun() then
return
end
self:run()
end
function InternetDetector:daemon()
if not self:preRun() then
return
end
-- UNIX double fork
if unistd.fork() == 0 then
unistd.setpid("s")
if unistd.fork() == 0 then
unistd.chdir("/")
stat.umask(0)
local devnull = fcntl.open("/dev/null", fcntl.O_RDWR)
io.stdout:flush()
io.stderr:flush()
unistd.dup2(devnull, 0) -- io.stdin
unistd.dup2(devnull, 1) -- io.stdout
unistd.dup2(devnull, 2) -- io.stderr
self:run()
unistd.close(devnull)
end
os.exit(0)
end
os.exit(0)
end
function InternetDetector:setServiceConfig(instance)
if self:loadUCIConfig("instance", instance) then
self:parseHosts()
if self.mode == 2 then
self.enableLogger = false
self.noModules = true
end
return true
end
end
-- Main section
local InternetDetector = require("internet-detector.main")
local function help()
return string.format(

View File

@@ -1,147 +0,0 @@
--[[
Dependences:
mailsend
--]]
local unistd = require("posix.unistd")
local Module = {
name = "mod_email",
runPrio = 60,
config = {
debug = false,
},
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
readValue = function(filePath) return nil end,
alivePeriod = 0,
hostAlias = "OpenWrt",
mta = "/usr/bin/mailsend",
mailRecipient = "email@gmail.com",
mailSender = "email@gmail.com",
mailUser = "email@gmail.com",
mailPassword = "password",
mailSmtp = "smtp.gmail.com",
mailSmtpPort = '587',
mailSecurity = "tls",
status = nil,
_enabled = false,
_aliveCounter = 0,
_msgSent = true,
_disconnected = true,
_lastDisconnection = nil,
_lastConnection = nil,
}
function Module:init(t)
self.alivePeriod = tonumber(t.alive_period)
if t.host_alias then
self.hostAlias = t.host_alias
else
self.hostAlias = self.config.hostname
end
self.mailRecipient = t.mail_recipient
self.mailSender = t.mail_sender
self.mailUser = t.mail_user
self.mailPassword = t.mail_password
self.mailSmtp = t.mail_smtp
self.mailSmtpPort = t.mail_smtp_port
self.mailSecurity = t.mail_security
if unistd.access(self.mta, "x") then
self._enabled = true
else
self._enabled = false
self.syslog("warning", string.format("%s: %s is not available", self.name, self.mta))
end
if (not self.mailRecipient or
not self.mailSender or
not self.mailUser or
not self.mailPassword or
not self.mailSmtp or
not self.mailSmtpPort) then
self._enabled = false
self.syslog("warning", string.format(
"%s: Insufficient data to connect to the SMTP server", self.name))
end
end
function Module:sendMessage(msg)
local verboseArg = ""
-- Debug
if self.config.debug then
verboseArg = " -v"
io.stdout:write(string.format("--- %s ---\n", self.name))
io.stdout:flush()
end
local securityArgs = "-starttls -auth-login"
if self.mailSecurity == "ssl" then
securityArgs = "-ssl -auth"
end
local mtaCmd = string.format(
'%s%s %s -smtp "%s" -port %s -cs utf-8 -user "%s" -pass "%s" -f "%s" -t "%s" -sub "%s" -M "%s"',
self.mta, verboseArg, securityArgs, self.mailSmtp, self.mailSmtpPort,
self.mailUser, self.mailPassword, self.mailSender, self.mailRecipient,
string.format("%s notification", self.hostAlias),
string.format("%s:\n%s", self.hostAlias, msg))
if os.execute(mtaCmd) ~= 0 then
self.syslog("err", string.format(
"%s: An error occured while sending message", self.name))
else
self.syslog("info", string.format(
"%s: Message sent to %s", self.name, self.mailRecipient))
end
end
function Module:run(currentStatus, lastStatus, timeDiff)
if not self._enabled then
return
end
if currentStatus == 1 then
self._aliveCounter = 0
self._msgSent = false
self._lastConnection = nil
if not self._disconnected then
self._disconnected = true
if not self._lastDisconnection then
self._lastDisconnection = os.date("%Y.%m.%d %H:%M:%S", os.time())
end
end
else
if not self._msgSent then
if not self._lastConnection then
self._lastConnection = os.date("%Y.%m.%d %H:%M:%S", os.time())
end
if self._aliveCounter >= self.alivePeriod then
local message = {}
if self._lastDisconnection then
message[#message + 1] = string.format(
"Internet disconnected: %s", self._lastDisconnection)
self._lastDisconnection = nil
end
if self._lastConnection then
message[#message + 1] = string.format(
"Internet connected: %s", self._lastConnection)
self:sendMessage(table.concat(message, ", "))
self._msgSent = true
end
else
self._aliveCounter = self._aliveCounter + timeDiff
end
end
self._disconnected = false
end
end
return Module

View File

@@ -1,86 +0,0 @@
--[[
Dependences:
modemmanager
--]]
local unistd = require("posix.unistd")
local Module = {
name = "mod_modem_restart",
runPrio = 40,
config = {},
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
readValue = function(filePath) return nil end,
mmcli = "/usr/bin/mmcli",
mmInit = "/etc/init.d/modemmanager",
deadPeriod = 0,
iface = nil,
anyBand = false,
status = nil,
_enabled = false,
_deadCounter = 0,
_restarted = false,
}
function Module:toggleIface(flag)
return os.execute(
string.format("%s %s", (flag and "/sbin/ifup" or "/sbin/ifdown"), self.iface)
)
end
function Module:restartMM()
if self.anyBand then
self.syslog("info", string.format(
"%s: resetting current-bands to 'any'", self.name))
os.execute(string.format("%s -m any --set-current-bands=any", self.mmcli))
end
self.syslog("info", string.format("%s: reconnecting modem", self.name))
os.execute(string.format("%s restart", self.mmInit))
if self.iface then
self.syslog("info", string.format(
"%s: restarting network interface '%s'", self.name, self.iface))
self:toggleIface(false)
self:toggleIface(true)
end
end
function Module:init(t)
self.deadPeriod = tonumber(t.dead_period)
self.iface = t.iface
self.anyBand = (tonumber(t.any_band) ~= 0)
if not unistd.access(self.mmcli, "x") then
self.anyBand = false
end
if unistd.access(self.mmInit, "x") then
self._enabled = true
else
self._enabled = false
self.syslog("warning", string.format(
"%s: modemmanager service is not available", self.name))
end
end
function Module:run(currentStatus, lastStatus, timeDiff)
if not self._enabled then
return
end
if currentStatus == 1 then
if not self._restarted then
if self._deadCounter >= self.deadPeriod then
self:restartMM()
self._restarted = true
else
self._deadCounter = self._deadCounter + timeDiff
end
end
else
self._deadCounter = 0
self._restarted = false
end
end
return Module

View File

@@ -0,0 +1,643 @@
local dirent = require("posix.dirent")
local fcntl = require("posix.fcntl")
local signal = require("posix.signal")
local socket = require("posix.sys.socket")
local stat = require("posix.sys.stat")
local syslog = require("posix.syslog")
local time = require("posix.time")
local unistd = require("posix.unistd")
local uci = require("uci")
-- Default settings
local InternetDetector = {
mode = 0, -- 0: disabled, 1: Service, 2: UI detector
enableLogger = true,
hostname = "OpenWrt",
appName = "internet-detector",
commonDir = "/tmp/run",
libDir = "/usr/lib/lua",
pingCmd = "/bin/ping",
pingParams = "-c 1",
uiRunTime = 30,
noModules = false,
uiAvailModules = { mod_public_ip = true },
debug = false,
serviceConfig = {
hosts = {
[1] = "8.8.8.8",
[2] = "1.1.1.1",
},
check_type = 0, -- 0: TCP, 1: ICMP
tcp_port = 53,
icmp_packet_size = 56,
interval_up = 30,
interval_down = 5,
connection_attempts = 2,
connection_timeout = 2,
iface = nil,
instance = nil,
},
modules = {},
parsedHosts = {},
uiCounter = 0,
}
InternetDetector.configDir = string.format("/etc/%s", InternetDetector.appName)
InternetDetector.modulesDir = string.format(
"%s/%s", InternetDetector.libDir, InternetDetector.appName)
-- Loading settings from UCI
local uciCursor = uci.cursor()
local mode, err = uciCursor:get(InternetDetector.appName, "config", "mode")
if mode ~= nil then
InternetDetector.mode = tonumber(mode)
elseif err then
io.stderr:write(string.format("Error: %s\n", err))
end
local enableLogger, err = uciCursor:get(InternetDetector.appName, "config", "enable_logger")
if enableLogger ~= nil then
InternetDetector.enableLogger = (tonumber(enableLogger) ~= 0)
elseif err then
io.stderr:write(string.format("Error: %s\n", err))
end
local hostname, err = uciCursor:get("system", "@[0]", "hostname")
if hostname ~= nil then
InternetDetector.hostname = hostname
elseif err then
io.stderr:write(string.format("Error: %s\n", err))
end
local _RUNNING
function InternetDetector:prequire(package)
local retVal, pkg = pcall(require, package)
return retVal and pkg
end
function InternetDetector:loadUCIConfig(sType, instance)
local success
local num = 0
uciCursor:foreach(
self.appName,
sType,
function(s)
if s[".name"] == instance then
for k, v in pairs(s) do
if type(v) == "string" and v:match("^[%d]+$") then
v = tonumber(v)
end
self.serviceConfig[k] = v
end
success = true
self.serviceConfig.instanceNum = num
end
num = num + 1
end
)
self.serviceConfig.instance = instance
self.pidFile = string.format(
"%s/%s.%s.pid", self.commonDir, self.appName, instance)
self.statusFile = string.format(
"%s/%s.%s.status", self.commonDir, self.appName, instance)
return success
end
function InternetDetector:writeValueToFile(filePath, str)
local retValue = false
local fh = io.open(filePath, "w")
if fh then
fh:setvbuf("no")
fh:write(string.format("%s\n", str))
fh:close()
retValue = true
end
return retValue
end
function InternetDetector:readValueFromFile(filePath)
local retValue
local fh = io.open(filePath, "r")
if fh then
retValue = fh:read("*l")
fh:close()
end
return retValue
end
function InternetDetector:statusJson(inet, instance, t)
local lines = { [1] = string.format(
'{"instance":"%s","num":"%d","inet":%d',
instance,
self.serviceConfig.instanceNum,
inet)}
if t then
for k, v in pairs(t) do
lines[#lines + 1] = string.format('"%s":"%s"', k, v)
end
end
return table.concat(lines, ",") .. "}"
end
function InternetDetector:writeLogMessage(level, msg)
if self.enableLogger then
local levels = {
emerg = syslog.LOG_EMERG,
alert = syslog.LOG_ALERT,
crit = syslog.LOG_CRIT,
err = syslog.LOG_ERR,
warning = syslog.LOG_WARNING,
notice = syslog.LOG_NOTICE,
info = syslog.LOG_INFO,
debug = syslog.LOG_DEBUG,
}
syslog.syslog(levels[level] or syslog.LOG_INFO, string.format(
"%s: %s", self.serviceConfig.instance or "", msg))
end
end
function InternetDetector:loadModules()
self.modules = {}
local ok, modulesDir = pcall(dirent.files, self.modulesDir)
if ok then
for item in modulesDir do
if item:match("^mod_") then
local modName = item:gsub("%.lua$", "")
if self.noModules and not self.uiAvailModules[modName] then
else
local modConfig = {}
for k, v in pairs(self.serviceConfig) do
if k:match("^" .. modName) then
modConfig[k:gsub("^" .. modName .. "_", "")] = v
end
end
if modConfig.enabled == 1 then
local m
if self.debug then
m = require(string.format("%s.%s", self.appName, modName))
else
m = self:prequire(string.format("%s.%s", self.appName, modName))
end
if m then
m.config = self
m.syslog = function(level, msg) self:writeLogMessage(level, msg) end
m.writeValue = function(filePath, str) return self:writeValueToFile(filePath, str) end
m.readValue = function(filePath) return self:readValueFromFile(filePath) end
m:init(modConfig)
self.modules[#self.modules + 1] = m
end
end
end
end
end
table.sort(self.modules, function(a, b) return a.runPrio < b.runPrio end)
end
end
function InternetDetector:parseHost(host)
local addr, port = host:match("^([^%[%]:]+):?(%d?%d?%d?%d?%d?)$")
if not addr then
addr, port = host:match("^%[?([^%[%]]+)%]?:?(%d?%d?%d?%d?%d?)$")
end
return addr, tonumber(port)
end
function InternetDetector:parseHosts()
self.parsedHosts = {}
for k, v in ipairs(self.serviceConfig.hosts) do
local addr, port = self:parseHost(v)
self.parsedHosts[k] = { addr = addr, port = port }
end
end
function InternetDetector:pingHost(host)
local ping = string.format(
"%s %s -W %d -s %d%s %s > /dev/null 2>&1",
self.pingCmd,
self.pingParams,
self.serviceConfig.connection_timeout,
self.serviceConfig.icmp_packet_size,
self.serviceConfig.iface and (" -I " .. self.serviceConfig.iface) or "",
host
)
local retCode = os.execute(ping)
if self.debug then
io.stdout:write(string.format(
"--- Ping ---\ntime = %s\n%s\nretCode = %s\n", os.time(), ping, retCode)
)
io.stdout:flush()
end
return retCode
end
function InternetDetector:TCPConnectionToHost(host, port)
local retCode = 1
local saTable, errMsg, errNum = socket.getaddrinfo(host, port or self.serviceConfig.tcp_port)
if not saTable then
if self.debug then
io.stdout:write(string.format(
"GETADDRINFO ERROR: %s, %s\n", errMsg, errNum))
end
else
local family = saTable[1].family
if family then
local sock, errMsg, errNum = socket.socket(family, socket.SOCK_STREAM, 0)
if not sock then
if self.debug then
io.stdout:write(string.format(
"SOCKET ERROR: %s, %s\n", errMsg, errNum))
end
return retCode
end
socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_SNDTIMEO, self.serviceConfig.connection_timeout, 0)
socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_RCVTIMEO, self.serviceConfig.connection_timeout, 0)
if self.serviceConfig.iface then
local ok, errMsg, errNum = socket.setsockopt(sock, socket.SOL_SOCKET,
socket.SO_BINDTODEVICE, self.serviceConfig.iface)
if not ok then
if self.debug then
io.stdout:write(string.format(
"SOCKET ERROR: %s, %s\n", errMsg, errNum))
end
unistd.close(sock)
return retCode
end
end
local success = socket.connect(sock, saTable[1])
if self.debug then
if not success then
io.stdout:write(string.format(
"SOCKET CONNECT ERROR: %s\n", tostring(success)))
end
local sockTable, err_s, e_s = socket.getsockname(sock)
local peerTable, err_p, e_p = socket.getpeername(sock)
if not sockTable then
sockTable = {}
io.stdout:write(
string.format("SOCKET ERROR: %s, %s\n", err_s, e_s))
end
if not peerTable then
peerTable = {}
io.stdout:write(
string.format("SOCKET ERROR: %s, %s\n", err_p, e_p))
end
io.stdout:write(string.format(
"--- TCP ---\ntime = %s\nconnection_timeout = %s\niface = %s\nhost:port = [%s]:%s\nsockname = [%s]:%s\npeername = [%s]:%s\nsuccess = %s\n",
os.time(),
self.serviceConfig.connection_timeout,
tostring(self.serviceConfig.iface),
host,
port or self.serviceConfig.tcp_port,
tostring(sockTable.addr),
tostring(sockTable.port),
tostring(peerTable.addr),
tostring(peerTable.port),
tostring(success))
)
io.stdout:flush()
end
socket.shutdown(sock, socket.SHUT_RDWR)
unistd.close(sock)
retCode = success and 0 or 1
end
end
return retCode
end
function InternetDetector:checkHosts()
local checkFunc = (self.serviceConfig.check_type == 1) and self.pingHost or self.TCPConnectionToHost
local retCode = 1
for k, v in ipairs(self.parsedHosts) do
for i = 1, self.serviceConfig.connection_attempts do
if checkFunc(self, v.addr, v.port) == 0 then
retCode = 0
break
end
end
if retCode == 0 then
break
end
end
return retCode
end
function InternetDetector:breakMainLoop(signo)
_RUNNING = false
end
function InternetDetector:resetUiCounter(signo)
self.uiCounter = 0
end
function InternetDetector:mainLoop()
signal.signal(signal.SIGTERM, function(signo) self:breakMainLoop(signo) end)
signal.signal(signal.SIGINT, function(signo) self:breakMainLoop(signo) end)
signal.signal(signal.SIGQUIT, function(signo) self:breakMainLoop(signo) end)
signal.signal(signal.SIGUSR1, function(signo) self:resetUiCounter(signo) end)
local lastStatus, currentStatus, mTimeNow, mTimeDiff, mLastTime, uiTimeNow, uiLastTime
local interval = self.serviceConfig.interval_up
local counter = 0
local onStart = true
_RUNNING = true
while _RUNNING do
if counter == 0 or counter >= interval then
currentStatus = self:checkHosts()
if onStart or not stat.stat(self.statusFile) then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
onStart = false
end
if currentStatus == 0 then
interval = self.serviceConfig.interval_up
if lastStatus ~= nil and currentStatus ~= lastStatus then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
self:writeLogMessage("notice", "Connected")
end
else
interval = self.serviceConfig.interval_down
if lastStatus ~= nil and currentStatus ~= lastStatus then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance))
self:writeLogMessage("notice", "Disconnected")
end
end
counter = 0
end
mTimeDiff = 0
for _, e in ipairs(self.modules) do
mTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec
if mLastTime then
mTimeDiff = mTimeDiff + mTimeNow - mLastTime
else
mTimeDiff = 1
end
mLastTime = mTimeNow
e:run(currentStatus, lastStatus, mTimeDiff)
end
local modulesStatus = {}
for k, v in ipairs(self.modules) do
if v.status ~= nil then
modulesStatus[v.name] = v.status
end
end
if next(modulesStatus) then
self:writeValueToFile(self.statusFile, self:statusJson(
currentStatus, self.serviceConfig.instance, modulesStatus))
end
lastStatus = currentStatus
unistd.sleep(1)
counter = counter + 1
if self.mode == 2 then
uiTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec
if uiLastTime then
self.uiCounter = self.uiCounter + uiTimeNow - uiLastTime
else
self.uiCounter = self.uiCounter + 1
end
uiLastTime = uiTimeNow
if self.uiCounter >= self.uiRunTime then
self:breakMainLoop(signal.SIGTERM)
end
end
end
end
function InternetDetector:removeProcessFiles()
os.remove(string.format(
"%s/%s.%s.pid", self.commonDir, self.appName, self.serviceConfig.instance))
os.remove(string.format(
"%s/%s.%s.status", self.commonDir, self.appName, self.serviceConfig.instance))
end
function InternetDetector:status()
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
local appName = self.appName:gsub("-", "%%-")
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
return "running"
end
end
end
return "stoped"
end
function InternetDetector:inetStatus()
local inetStat = '{"instances":[]}'
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
local appName = self.appName:gsub("-", "%%-")
local lines = {}
for item in commonDir do
if item:match("^" .. appName .. ".-%.status$") then
lines[#lines + 1] = self:readValueFromFile(
string.format("%s/%s", self.commonDir, item))
end
end
inetStat = '{"instances":[' .. table.concat(lines, ",") .. "]}"
end
return inetStat
end
function InternetDetector:stopInstance(pidFile)
local retVal
if stat.stat(pidFile) then
pidValue = self:readValueFromFile(pidFile)
if pidValue then
local ok, errMsg, errNum
for i = 0, 10 do
ok, errMsg, errNum = signal.kill(tonumber(pidValue), signal.SIGTERM)
if ok then
break
end
end
if not ok then
io.stderr:write(string.format(
'Process stop error: %s (%s). PID: "%s"\n', errMsg, errNum, pidValue))
end
if errNum == 3 then
os.remove(pidFile)
end
retVal = true
end
end
if not pidValue then
io.stderr:write(
string.format('PID file "%s" does not exist. %s not running?\n',
pidFile, self.appName))
end
return retVal
end
function InternetDetector:stop()
local appName = self.appName:gsub("-", "%%-")
local success
for i = 0, 10 do
success = true
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
self:stopInstance(string.format("%s/%s", self.commonDir, item))
success = false
end
end
if success then
break
end
unistd.sleep(1)
else
break
end
end
end
function InternetDetector:setSIGUSR()
local appName = self.appName:gsub("-", "%%-")
local ok, commonDir = pcall(dirent.files, self.commonDir)
if ok then
for item in commonDir do
if item:match("^" .. appName .. ".-%.pid$") then
pidValue = self:readValueFromFile(string.format("%s/%s", self.commonDir, item))
if pidValue then
signal.kill(tonumber(pidValue), signal.SIGUSR1)
end
end
end
end
end
function InternetDetector:preRun()
-- Exit if internet-detector mode != (1 or 2)
if self.mode ~= 1 and self.mode ~= 2 then
io.stderr:write(string.format('Start failed, mode != (1 or 2)\n', self.appName))
os.exit(0)
end
if stat.stat(self.pidFile) then
io.stderr:write(
string.format('PID file "%s" already exist. %s already running?\n',
self.pidFile, self.appName))
return false
end
return true
end
function InternetDetector:run()
local pidValue = unistd.getpid()
self:writeValueToFile(self.pidFile, pidValue)
if self.enableLogger then
syslog.openlog(self.appName, syslog.LOG_PID, syslog.LOG_DAEMON)
end
self:writeLogMessage("info", "started")
self:loadModules()
-- Loaded modules
local modules = {}
for _, v in ipairs(self.modules) do
modules[#modules + 1] = string.format("%s", v.name)
end
if #modules > 0 then
self:writeLogMessage(
"info", string.format("Loaded modules: %s", table.concat(modules, ", "))
)
end
if self.debug then
local function inspectTable()
local tables = {}, f
f = function(t, prefix)
tables[t] = true
for k, v in pairs(t) do
io.stdout:write(string.format(
"%s%s = %s\n", prefix, k, tostring(v))
)
if type(v) == "table" and not tables[v] then
f(v, string.format("%s%s.", prefix, k))
end
end
end
return f
end
io.stdout:write("--- Config ---\n")
inspectTable()(self, "self.")
io.stdout:flush()
end
self:writeValueToFile(
self.statusFile, self:statusJson(-1, self.serviceConfig.instance))
self:mainLoop()
self:removeProcessFiles()
if self.enableLogger then
self:writeLogMessage("info", "stoped")
syslog.closelog()
end
end
function InternetDetector:noDaemon()
if not self:preRun() then
return
end
self:run()
end
function InternetDetector:daemon()
if not self:preRun() then
return
end
-- UNIX double fork
if unistd.fork() == 0 then
unistd.setpid("s")
if unistd.fork() == 0 then
unistd.chdir("/")
stat.umask(0)
local devnull = fcntl.open("/dev/null", fcntl.O_RDWR)
io.stdout:flush()
io.stderr:flush()
unistd.dup2(devnull, 0) -- io.stdin
unistd.dup2(devnull, 1) -- io.stdout
unistd.dup2(devnull, 2) -- io.stderr
self:run()
unistd.close(devnull)
end
os.exit(0)
end
os.exit(0)
end
function InternetDetector:setServiceConfig(instance)
if self:loadUCIConfig("instance", instance) then
self:parseHosts()
if self.mode == 2 then
self.enableLogger = false
self.noModules = true
end
return true
end
end
return InternetDetector

View File

@@ -38,12 +38,17 @@ function Module:resetLeds()
end
function Module:init(t)
self.ledName = t.led_name
if not self.ledName then
if not t.led_name then
return
else
self.ledName = t.led_name
end
if t.led_action_1 ~= nil then
self.ledAction1 = tonumber(t.led_action_1)
end
if t.led_action_2 ~= nil then
self.ledAction2 = tonumber(t.led_action_2)
end
self.ledAction1 = tonumber(t.led_action_1)
self.ledAction2 = tonumber(t.led_action_2)
self._ledDir = string.format("%s/%s", self.sysLedsDir, self.ledName)
self._ledMaxBrightnessFile = string.format("%s/max_brightness", self._ledDir)
self._ledBrightnessFile = string.format("%s/brightness", self._ledDir)

View File

@@ -8,9 +8,9 @@ local Module = {
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
readValue = function(filePath) return nil end,
iface = false,
attempts = 0,
deadPeriod = 0,
deadPeriod = 900,
attempts = 1,
iface = nil,
restartTimeout = 0,
status = nil,
_attemptsCounter = 0,
@@ -22,6 +22,9 @@ function Module:toggleFunc(flag)
end
function Module:toggleDevice(flag)
if not self.iface then
return
end
local ip = "/sbin/ip"
if unistd.access(ip, "x") then
return os.execute(string.format(
@@ -31,6 +34,9 @@ function Module:toggleDevice(flag)
end
function Module:toggleIface(flag)
if not self.iface then
return
end
return os.execute(
string.format("%s %s", (flag and "/sbin/ifup" or "/sbin/ifdown"), self.iface)
)
@@ -59,9 +65,15 @@ function Module:init(t)
self.toggleFunc = self.toggleDevice
end
end
self.attempts = tonumber(t.attempts)
self.deadPeriod = tonumber(t.dead_period)
self.restartTimeout = tonumber(t.restart_timeout)
if t.attempts ~= nil then
self.attempts = tonumber(t.attempts)
end
if t.dead_period ~= nil then
self.deadPeriod = tonumber(t.dead_period)
end
if t.restart_timeout ~= nil then
self.restartTimeout = tonumber(t.restart_timeout)
end
end
function Module:run(currentStatus, lastStatus, timeDiff)

View File

@@ -20,7 +20,6 @@ local Module = {
runInterval = 600,
runIntervalFailed = 60,
timeout = 3,
reqAttempts = 3,
providers = {
opendns1 = {
name = "opendns1", host = "myip.opendns.com",
@@ -333,13 +332,13 @@ function Module:resolveIP()
end
function Module:init(t)
if t.interval then
if t.interval ~= nil then
self.runInterval = tonumber(t.interval)
end
if t.timeout then
if t.timeout ~= nil then
self.timeout = tonumber(t.timeout)
end
if t.provider then
if t.provider ~= nil then
self._provider = self.providers[t.provider]
else
self._provider = self.providers.opendns1
@@ -347,11 +346,13 @@ function Module:init(t)
if self.config.configDir then
self.ipScript = string.format(
"%s/public-ip-script.%s", self.config.configDir, self.config.serviceConfig.instance)
if t.enable_ip_script then
if t.enable_ip_script ~= nil then
self.enableIpScript = (tonumber(t.enable_ip_script) ~= 0)
end
end
self._qtype = (tonumber(t.qtype) ~= 0)
if t.qtype ~= nil then
self._qtype = (tonumber(t.qtype) ~= 0)
end
self._currentIp = nil
self._DNSPacket = nil
self._interval = self.runInterval

View File

@@ -8,8 +8,8 @@ local Module = {
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
readValue = function(filePath) return nil end,
deadPeriod = 0,
forceRebootDelay = 0,
deadPeriod = 3600,
forceRebootDelay = 300,
status = nil,
_deadCounter = 0,
}
@@ -26,8 +26,12 @@ function Module:rebootDevice()
end
function Module:init(t)
self.deadPeriod = tonumber(t.dead_period)
self.forceRebootDelay = tonumber(t.force_reboot_delay)
if t.dead_period ~= nil then
self.deadPeriod = tonumber(t.dead_period)
end
if t.force_reboot_delay ~= nil then
self.forceRebootDelay = tonumber(t.force_reboot_delay)
end
end
function Module:run(currentStatus, lastStatus, timeDiff)

View File

@@ -3,7 +3,7 @@ local unistd = require("posix.unistd")
local Module = {
name = "mod_user_scripts",
runPrio = 70,
runPrio = 80,
config = {},
syslog = function(level, msg) return true end,
writeValue = function(filePath, str) return false end,
@@ -26,8 +26,12 @@ function Module:runExternalScript(scriptPath)
end
function Module:init(t)
self.deadPeriod = tonumber(t.dead_period)
self.alivePeriod = tonumber(t.alive_period)
if t.dead_period ~= nil then
self.deadPeriod = tonumber(t.dead_period)
end
if t.alive_period ~= nil then
self.alivePeriod = tonumber(t.alive_period)
end
if self.config.configDir then
self.upScript = string.format(
"%s/up-script.%s", self.config.configDir, self.config.serviceConfig.instance)