base.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. require("luci.sys")
  2. require("luci.util")
  3. require("io")
  4. local m,s,o,o1
  5. local fs=require"nixio.fs"
  6. local uci=require"luci.model.uci".cursor()
  7. local configpath=uci:get("AdGuardHome","AdGuardHome","configpath") or "/etc/AdGuardHome.yaml"
  8. local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") or "/usr/bin/AdGuardHome/AdGuardHome"
  9. httpport=uci:get("AdGuardHome","AdGuardHome","httpport") or "3000"
  10. m = Map("AdGuardHome", "AdGuard Home")
  11. m.description = translate("Free and open source, powerful network-wide ads & trackers blocking DNS server.")
  12. m:section(SimpleSection).template = "AdGuardHome/AdGuardHome_status"
  13. s = m:section(TypedSection, "AdGuardHome")
  14. s.anonymous=true
  15. s.addremove=false
  16. ---- enable
  17. o = s:option(Flag, "enabled", translate("Enable"))
  18. o.default = 0
  19. o.optional = false
  20. ---- httpport
  21. o =s:option(Value,"httpport",translate("Browser management port"))
  22. o.placeholder=3000
  23. o.default=3000
  24. o.datatype="port"
  25. o.optional = false
  26. o.description = translate("<input type=\"button\" style=\"width:210px;border-color:Teal; text-align:center;font-weight:bold;color:Green;\" value=\"AdGuardHome Web:"..httpport.."\" onclick=\"window.open('http://'+window.location.hostname+':"..httpport.."/')\"/>")
  27. ---- update warning not safe
  28. local binmtime=uci:get("AdGuardHome","AdGuardHome","binmtime") or "0"
  29. local e=""
  30. if not fs.access(configpath) then
  31. e=e.." "..translate("no config")
  32. end
  33. if not fs.access(binpath) then
  34. e=e.." "..translate("no core")
  35. else
  36. local version=uci:get("AdGuardHome","AdGuardHome","version")
  37. local testtime=fs.stat(binpath,"mtime")
  38. if testtime~=tonumber(binmtime) or version==nil then
  39. local tmp=luci.sys.exec(binpath.." -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o")
  40. version=string.sub(tmp, 1, -2)
  41. if version=="" then version="core error" end
  42. uci:set("AdGuardHome","AdGuardHome","version",version)
  43. uci:set("AdGuardHome","AdGuardHome","binmtime",testtime)
  44. uci:save("AdGuardHome")
  45. end
  46. e=version..e
  47. end
  48. o=s:option(Button,"restart",translate("Update"))
  49. o.inputtitle=translate("Update core version")
  50. o.template = "AdGuardHome/AdGuardHome_check"
  51. o.showfastconfig=(not fs.access(configpath))
  52. o.description=string.format(translate("core version:").."<strong><font id=\"updateversion\" color=\"green\">%s </font></strong>",e)
  53. ---- port warning not safe
  54. local port=luci.sys.exec("awk '/ port:/{printf($2);exit;}' "..configpath.." 2>nul")
  55. if (port=="") then port="?" end
  56. ---- Redirect
  57. o = s:option(ListValue, "redirect", port..translate("Redirect"), translate("AdGuardHome redirect mode"))
  58. o.placeholder = "none"
  59. o:value("none", translate("none"))
  60. o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server"))
  61. o:value("redirect", translate("Redirect 53 port to AdGuardHome"))
  62. o:value("exchange", translate("Use port 53 replace dnsmasq"))
  63. o.default = "none"
  64. o.optional = true
  65. ---- bin path
  66. o = s:option(Value, "binpath", translate("Bin Path"), translate("AdGuardHome Bin path if no bin will auto download"))
  67. o.default = "/usr/bin/AdGuardHome/AdGuardHome"
  68. o.datatype = "string"
  69. o.optional = false
  70. o.rmempty=false
  71. o.validate=function(self, value)
  72. if value=="" then return nil end
  73. if fs.stat(value,"type")=="dir" then
  74. fs.rmdir(value)
  75. end
  76. if fs.stat(value,"type")=="dir" then
  77. if (m.message) then
  78. m.message =m.message.."\nerror!bin path is a dir"
  79. else
  80. m.message ="error!bin path is a dir"
  81. end
  82. return nil
  83. end
  84. return value
  85. end
  86. --- upx
  87. o = s:option(ListValue, "upxflag", translate("use upx to compress bin after download"))
  88. o:value("", translate("none"))
  89. o:value("-1", translate("compress faster"))
  90. o:value("-9", translate("compress better"))
  91. o:value("--best", translate("compress best(can be slow for big files)"))
  92. o:value("--brute", translate("try all available compression methods & filters [slow]"))
  93. o:value("--ultra-brute", translate("try even more compression variants [very slow]"))
  94. o.default = ""
  95. o.description=translate("bin use less space,but may have compatibility issues")
  96. o.rmempty = true
  97. ---- config path
  98. o = s:option(Value, "configpath", translate("Config Path"), translate("AdGuardHome config path"))
  99. o.default = "/etc/AdGuardHome.yaml"
  100. o.datatype = "string"
  101. o.optional = false
  102. o.rmempty=false
  103. o.validate=function(self, value)
  104. if value==nil then return nil end
  105. if fs.stat(value,"type")=="dir" then
  106. fs.rmdir(value)
  107. end
  108. if fs.stat(value,"type")=="dir" then
  109. if m.message then
  110. m.message =m.message.."\nerror!config path is a dir"
  111. else
  112. m.message ="error!config path is a dir"
  113. end
  114. return nil
  115. end
  116. return value
  117. end
  118. ---- work dir
  119. o = s:option(Value, "workdir", translate("Work dir"), translate("AdGuardHome work dir include rules,audit log and database"))
  120. o.default = "/usr/bin/AdGuardHome"
  121. o.datatype = "string"
  122. o.optional = false
  123. o.rmempty=false
  124. o.validate=function(self, value)
  125. if value=="" then return nil end
  126. if fs.stat(value,"type")=="reg" then
  127. if m.message then
  128. m.message =m.message.."\nerror!work dir is a file"
  129. else
  130. m.message ="error!work dir is a file"
  131. end
  132. return nil
  133. end
  134. if string.sub(value, -1)=="/" then
  135. return string.sub(value, 1, -2)
  136. else
  137. return value
  138. end
  139. end
  140. ---- log file
  141. o = s:option(Value, "logfile", translate("Runtime log file"), translate("AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"))
  142. o.datatype = "string"
  143. o.rmempty = true
  144. o.validate=function(self, value)
  145. if fs.stat(value,"type")=="dir" then
  146. fs.rmdir(value)
  147. end
  148. if fs.stat(value,"type")=="dir" then
  149. if m.message then
  150. m.message =m.message.."\nerror!log file is a dir"
  151. else
  152. m.message ="error!log file is a dir"
  153. end
  154. return nil
  155. end
  156. return value
  157. end
  158. ---- debug
  159. o = s:option(Flag, "verbose", translate("Verbose log"))
  160. o.default = 0
  161. o.optional = true
  162. ---- gfwlist
  163. local a=luci.sys.call("grep -m 1 -q programadd "..configpath)
  164. if (a==0) then
  165. a="Added"
  166. else
  167. a="Not added"
  168. end
  169. o=s:option(Button,"gfwdel",translate("Del gfwlist"),translate(a))
  170. o.optional = true
  171. o.inputtitle=translate("Del")
  172. o.write=function()
  173. luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh del 2>&1")
  174. luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
  175. end
  176. o=s:option(Button,"gfwadd",translate("Add gfwlist"),translate(a))
  177. o.optional = true
  178. o.inputtitle=translate("Add")
  179. o.write=function()
  180. luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh 2>&1")
  181. luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
  182. end
  183. o = s:option(Value, "gfwupstream", translate("Gfwlist upstream dns server"), translate("Gfwlist domain upstream dns service")..translate(a))
  184. o.default = "tcp://208.67.220.220:5353"
  185. o.datatype = "string"
  186. o.optional = true
  187. ---- chpass
  188. o = s:option(Value, "hashpass", translate("Change browser management password"), translate("Press load culculate model and culculate finally save/apply"))
  189. o.default = ""
  190. o.datatype = "string"
  191. o.template = "AdGuardHome/AdGuardHome_chpass"
  192. o.optional = true
  193. ---- upgrade protect
  194. o = s:option(MultiValue, "upprotect", translate("Keep files when system upgrade"))
  195. o:value("$binpath",translate("core bin"))
  196. o:value("$configpath",translate("config file"))
  197. o:value("$logfile",translate("log file"))
  198. o:value("$workdir/data/sessions.db",translate("sessions.db"))
  199. o:value("$workdir/data/stats.db",translate("stats.db"))
  200. o:value("$workdir/data/querylog.json",translate("querylog.json"))
  201. o:value("$workdir/data/filters",translate("filters"))
  202. o.widget = "checkbox"
  203. o.default = nil
  204. o.optional=true
  205. ---- wait net on boot
  206. o = s:option(Flag, "waitonboot", translate("On boot when network ok restart"))
  207. o.default = 1
  208. o.optional = true
  209. ---- backup workdir on shutdown
  210. local workdir=uci:get("AdGuardHome","AdGuardHome","workdir") or "/usr/bin/AdGuardHome"
  211. o = s:option(MultiValue, "backupfile", translate("Backup workdir files when shutdown"))
  212. o1 = s:option(Value, "backupwdpath", translate("Backup workdir path"))
  213. local name
  214. o:value("filters","filters")
  215. o:value("stats.db","stats.db")
  216. o:value("querylog.json","querylog.json")
  217. o:value("sessions.db","sessions.db")
  218. o1:depends ("backupfile", "filters")
  219. o1:depends ("backupfile", "stats.db")
  220. o1:depends ("backupfile", "querylog.json")
  221. o1:depends ("backupfile", "sessions.db")
  222. for name in fs.glob(workdir.."/data/*")
  223. do
  224. name=fs.basename (name)
  225. if name~="filters" and name~="stats.db" and name~="querylog.json" and name~="sessions.db" then
  226. o:value(name,name)
  227. o1:depends ("backupfile", name)
  228. end
  229. end
  230. o.widget = "checkbox"
  231. o.default = nil
  232. o.optional=false
  233. o.description=translate("Will be restore when workdir/data is empty")
  234. ----backup workdir path
  235. o1.default = "/usr/bin/AdGuardHome"
  236. o1.datatype = "string"
  237. o1.optional = false
  238. o1.validate=function(self, value)
  239. if fs.stat(value,"type")=="reg" then
  240. if m.message then
  241. m.message =m.message.."\nerror!backup dir is a file"
  242. else
  243. m.message ="error!backup dir is a file"
  244. end
  245. return nil
  246. end
  247. if string.sub(value,-1)=="/" then
  248. return string.sub(value, 1, -2)
  249. else
  250. return value
  251. end
  252. end
  253. ----Crontab
  254. o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab"))
  255. o:value("autoupdate",translate("Auto update core"))
  256. o:value("cutquerylog",translate("Auto tail querylog"))
  257. o:value("cutruntimelog",translate("Auto tail runtime log"))
  258. o:value("autohost",translate("Auto update ipv6 hosts and restart adh"))
  259. o:value("autogfw",translate("Auto update gfwlist and restart adh"))
  260. o.widget = "checkbox"
  261. o.default = nil
  262. o.optional=true
  263. ----downloadpath
  264. o = s:option(TextValue, "downloadlinks",translate("Download links for update"))
  265. o.optional = false
  266. o.rows = 4
  267. o.wrap = "soft"
  268. o.cfgvalue = function(self, section)
  269. return fs.readfile("/usr/share/AdGuardHome/links.txt")
  270. end
  271. o.write = function(self, section, value)
  272. fs.writefile("/usr/share/AdGuardHome/links.txt", value:gsub("\r\n", "\n"))
  273. end
  274. fs.writefile("/var/run/lucilogpos","0")
  275. function m.on_commit(map)
  276. if (fs.access("/var/run/AdGserverdis")) then
  277. io.popen("/etc/init.d/AdGuardHome reload &")
  278. return
  279. end
  280. local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest")
  281. if ucitracktest=="1" then
  282. return
  283. elseif ucitracktest=="0" then
  284. io.popen("/etc/init.d/AdGuardHome reload &")
  285. else
  286. if (fs.access("/var/run/AdGlucitest")) then
  287. uci:set("AdGuardHome","AdGuardHome","ucitracktest","0")
  288. io.popen("/etc/init.d/AdGuardHome reload &")
  289. else
  290. fs.writefile("/var/run/AdGlucitest","")
  291. if (ucitracktest=="2") then
  292. uci:set("AdGuardHome","AdGuardHome","ucitracktest","1")
  293. else
  294. uci:set("AdGuardHome","AdGuardHome","ucitracktest","2")
  295. end
  296. end
  297. uci:save("AdGuardHome")
  298. end
  299. end
  300. return m