base.lua 9.5 KB

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