🍕 Sync 2026-08-25 21:35:08
Merge-upstream / merge (push) Canceled after 0s

This commit is contained in:
github-actions[bot] committed 2026-08-25 21:35:08 +08:00
1 parent 357b27c00f
commit 67b93951e1
15 files changed
+370 -412

No files matched your search

+9 -7
View File
@@ -1,13 +1,15 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 ImmortalWrt.org
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI app for dae dashboard
LUCI_DEPENDS:=+daed +daed-geoip +daed-geosite
PKG_NAME:=luci-app-daed
PKG_VERSION:=1.4
PKG_RELEASE:=2
LUCI_TITLE:=LuCI Support for DAED
LUCI_DEPENDS:=+daed +zoneinfo-asia +luci-compat
LUCI_PKGARCH:=all
include $(TOPDIR)/feeds/luci/luci.mk
define Package/$(PKG_NAME)/conffiles
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,93 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
'use strict';
'require form';
'require poll';
'require rpc';
'require uci';
'require view';
const callServiceList = rpc.declare({
object: 'service',
method: 'list',
params: ['name'],
expect: { '': {} }
});
function getServiceStatus() {
return L.resolveDefault(callServiceList('daed'), {}).then(function(res) {
let isRunning = false;
try {
isRunning = res['daed']['instances']['daed']['running'];
} catch (e) { }
return isRunning;
});
}
function renderStatus(isRunning, port) {
let spanTemp = '<span style="color:%s"><strong>%s %s</strong></span>';
let renderHTML;
if (isRunning) {
let button = String.format('&#160;<a class="btn cbi-button" href="http://%s:%s" target="_blank" rel="noreferrer noopener">%s</a>',
window.location.hostname, port, _('Open Web Interface'));
renderHTML = spanTemp.format('green', _('daed'), _('RUNNING')) + button;
} else {
renderHTML = spanTemp.format('red', _('daed'), _('NOT RUNNING'));
}
return renderHTML;
}
return view.extend({
load: function() {
return Promise.all([
uci.load('daed')
]);
},
render: function(data) {
let m, s, o;
let webport = (uci.get(data[0], 'config', 'address') || '0.0.0.0:2023').split(':').slice(-1)[0];
m = new form.Map('daed', _('daed'),
_('A modern dashboard for dae.'));
s = m.section(form.TypedSection);
s.anonymous = true;
s.render = function() {
poll.add(function() {
return L.resolveDefault(getServiceStatus()).then(function(res) {
let view = document.getElementById('service_status');
view.innerHTML = renderStatus(res, webport);
});
});
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
E('p', { id: 'service_status' }, _('Collecting data…'))
]);
}
s = m.section(form.NamedSection, 'config', 'daed');
o = s.option(form.Flag, 'enabled', _('Enable'));
o.default = o.disabled;
o.rmempty = false;
o = s.option(form.Value, 'listen_addr', _('Listening address'));
o.datatype = 'ipaddrport(1)';
o.default = '0.0.0.0:2023';
o.rmempty = false;
o = s.option(form.Value, 'log_maxbackups', _('Max log backups'),
_('The maximum number of old log files to retain.'));
o.datatype = 'uinteger';
o.default = '1';
o = s.option(form.Value, 'log_maxsize', _('Max log size'),
_('The maximum size in megabytes of the log file before it gets rotated.'));
o.datatype = 'uinteger';
o.default = '5';
return m.render();
}
});
@@ -1,94 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
'use strict';
'require dom';
'require fs';
'require poll';
'require view';
return view.extend({
render() {
/* Thanks to luci-app-aria2 */
let css = ' \
#log_textarea { \
text-align: left; \
} \
#log_textarea pre { \
padding: .5rem; \
word-break: break-all; \
margin: 0; \
} \
.description { \
background-color: #33ccff; \
}';
let log_textarea = E('div', { 'id': 'log_textarea' },
E('img', {
'src': L.resource('icons/loading.svg'),
'alt': _('Loading...'),
'style': 'vertical-align:middle'
}, _('Collecting data…'))
);
poll.add(L.bind(function() {
return fs.read_direct('/var/log/daed/daed.log', 'text')
.then(function(content) {
let log = E('pre', { 'wrap': 'pre' }, [
content.trim() || _('Log is empty.')
]);
dom.content(log_textarea, log);
}).catch(function(e) {
let log;
if (e.toString().includes('NotFoundError'))
log = E('pre', { 'wrap': 'pre' }, [
_('Log file does not exist.')
]);
else
log = E('pre', { 'wrap': 'pre' }, [
_('Unknown error: %s').format(e)
]);
dom.content(log_textarea, log);
});
}));
const scrollDownButton = E('button', {
'id': 'scrollDownButton',
'class': 'cbi-button cbi-button-neutral',
}, _('Scroll to tail', 'scroll to bottom (the tail) of the log file')
);
scrollDownButton.addEventListener('click', () => {
scrollUpButton.focus();
});
const scrollUpButton = E('button', {
'id' : 'scrollUpButton',
'class': 'cbi-button cbi-button-neutral',
}, _('Scroll to head', 'scroll to top (the head) of the log file')
);
scrollUpButton.addEventListener('click', () => {
scrollDownButton.focus();
});
return E([
E('style', [ css ]),
E('h2', {}, [ _('Log') ]),
E('div', {'class': 'cbi-map'}, [
E('div', {'style': 'padding-bottom: 20px'}, [scrollDownButton]),
E('div', {'class': 'cbi-section'}, [
log_textarea,
E('div', {'style': 'text-align:right'},
E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval))
)
]),
E('div', {'style': 'padding-bottom: 20px'}, [scrollUpButton])
])
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});
+34
View File
@@ -0,0 +1,34 @@
local sys = require "luci.sys"
local http = require "luci.http"
module("luci.controller.daed", package.seeall)
function index()
if not nixio.fs.access("/etc/config/daed") then
return
end
entry({"admin", "services", "daed"}, alias("admin", "services", "daed", "setting"),_("DAED"), 58).dependent = true
entry({"admin", "services", "daed", "setting"}, cbi("daed/basic"), _("Base Setting"), 1).leaf=true
entry({"admin", "services", "daed", "daed"}, template("daed/daed"), _("Dashboard"), 2).leaf = true
entry({"admin", "services", "daed", "log"}, cbi("daed/log"), _("Logs"), 3).leaf = true
entry({"admin", "services", "daed_status"}, call("act_status"))
entry({"admin", "services", "daed", "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", "daed", "clear_log"}, call("clear_log")).leaf = true
end
function act_status()
local sys = require "luci.sys"
local e = { }
e.running = sys.call("pidof daed >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function get_log()
http.write(sys.exec("cat /var/log/daed/daed.log"))
end
function clear_log()
sys.call("true > /var/log/daed/daed.log")
end
@@ -0,0 +1,35 @@
local m, s ,o
m = Map("daed")
m.title = translate("DAED")
m.description = translate("DAE is a Linux high-performance transparent proxy solution based on eBPF, And DAED is a modern dashboard for dae.")
m:section(SimpleSection).template = "daed/daed_status"
s = m:section(TypedSection, "daed", translate("Global Settings"))
s.addremove = false
s.anonymous = true
o = s:option(Flag,"enabled",translate("Enable"))
o.default = 0
o = s:option(Value, "log_maxbackups", translate("Logfile retention count"))
o.default = 1
o = s:option(Value, "log_maxsize", translate("Logfile Max Size (MB)"))
o.default = 5
o = s:option(Value, "listen_addr",translate("Set the DAED listen address"))
o.default = '0.0.0.0:2023'
o = s:option(Value, "dashboard_port", translate("Dashboard Access Port"))
o.placeholder = translate("Leave empty to use listen port")
o.datatype = "range(1,65535)"
o.description = translate("For reverse proxy scenarios, leave empty to use the port from listen address")
m.apply_on_parse = true
m.on_after_apply = function(self,map)
luci.sys.exec("/etc/init.d/daed restart")
end
return m
@@ -0,0 +1,5 @@
m = Map("daed")
m:append(Template("daed/daed_log"))
return m
+56
View File
@@ -0,0 +1,56 @@
<%+header%>
<%
local running = luci.sys.exec("pgrep -x /usr/bin/daed")
%>
<% if tonumber(running) ~= nil then %>
<div class="cbi-map">
<iframe id="daed" class="daed-iframe"></iframe>
</div>
<style>
.daed-iframe {
width: 100%;
height: 100vh;
min-height: 780px;
border: none;
border-radius: .375rem;
box-shadow: rgba(0, 0, 0, 0.75) 0px 0px 15px -5px;
display: block;
}
</style>
<script type="text/javascript">
var listenAddr = "<%=luci.model.uci.cursor():get_first("daed", "daed", "listen_addr") or ''%>";
var dashboardPort = "<%=luci.model.uci.cursor():get_first("daed", "daed", "dashboard_port") or ''%>";
var port = "";
if (dashboardPort && dashboardPort.trim() !== "") {
port = dashboardPort.trim();
} else {
var portRegex = /:(\d+)/;
var match = listenAddr.match(portRegex);
if (match && match[1]) {
port = match[1];
}
}
if (port) {
var protocol = window.location.protocol;
var hostname = window.location.hostname;
var url = protocol + "//" + hostname;
if (!((protocol === "http:" && port === "80") || (protocol === "https:" && port === "443"))) {
url += ":" + port;
}
document.getElementById("daed").src = url;
}
</script>
<% else %>
<style>.notrunning{text-align: center;} h1{font-size: 25px; color: #333; margin-bottom: 16px;} p{font-size: 18px; color: #666; margin-bottom: 24px;}</style>
<div class="notrunning">
<img src="data:image/png;base64,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 truncated
<h1><font color="color:red"><%:DAED is not running%></font></h1>
<p><%:Please start the DAED service first and try again%></p>
</div>
<% end -%>
<%+footer%>
@@ -0,0 +1,33 @@
<script type="text/javascript">
//<![CDATA[
function clear_log(btn) {
XHR.get('<%=url([[admin]], [[services]], [[daed]], [[clear_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = "";
log_textarea.scrollTop = log_textarea.scrollHeight;
}
location.reload();
}
);
}
var scrolled = false;
XHR.poll(2, '<%=url([[admin]], [[services]], [[daed]], [[get_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = x.responseText;
if (!scrolled) {
log_textarea.scrollTop = log_textarea.scrollHeight;
scrolled = true;
}
}
}
);
//]]>
</script>
<fieldset class="cbi-section" id="_log_fieldset">
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>" style="margin-left: 10px; margin-top: 10px;">
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); height: 645px; margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
</fieldset>
@@ -0,0 +1,24 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[daed_status]])%>', null,
function(x, data) {
var tb = document.getElementById('daed_status');
if (data && tb)
{
if (data.running)
{
tb.innerHTML = '<em><b style=\"color:green\"><%:DAED%> <%:RUNNING%></b></em>';
}
else
{
tb.innerHTML = '<em><b style=\"color:red\"><%:DAED%> <%:NOT RUNNING%></b></em>';
}
}
}
);
//]]></script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="daed_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
-97
View File
@@ -1,97 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:53
msgid "A modern dashboard for dae."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:66
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:30
msgid "Collecting data…"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:72
msgid "Enable"
msgstr ""
#: applications/luci-app-daed/root/usr/share/rpcd/acl.d/luci-app-daed.json:3
msgid "Grant access to daed configuration"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:76
msgid "Listening address"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:28
msgid "Loading..."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:77
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:22
msgid "Log"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:46
msgid "Log file does not exist."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:37
msgid "Log is empty."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:81
msgid "Max log backups"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:86
msgid "Max log size"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:35
msgid "NOT RUNNING"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:32
msgid "Open Web Interface"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:33
msgid "RUNNING"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:83
msgid "Refresh every %s seconds."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:69
msgctxt "scroll to top (the head) of the log file"
msgid "Scroll to head"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:60
msgctxt "scroll to bottom (the tail) of the log file"
msgid "Scroll to tail"
msgstr ""
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:14
msgid "Settings"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:82
msgid "The maximum number of old log files to retain."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:87
msgid "The maximum size in megabytes of the log file before it gets rotated."
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:50
msgid "Unknown error: %s"
msgstr ""
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:33
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:35
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:52
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:3
msgid "daed"
msgstr ""
+49 -85
View File
@@ -1,104 +1,68 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: zh-Hans\n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
msgstr "Content-Type: text/plain; charset=UTF-8"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:53
msgid "A modern dashboard for dae."
msgstr "dae 现代化控制面板。"
msgid "DAED"
msgstr "DAED"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:66
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:30
msgid "Collecting data…"
msgstr "正在收集数据中…"
msgid "DAE is a Linux high-performance transparent proxy solution based on eBPF, And DAED is a modern dashboard for dae."
msgstr "DAE是一个基于eBPF的Linux高性能透明代理解决方案,而DAED是DAE的管理面板。"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:72
msgid "Enable"
msgstr "启用"
msgid "Base Setting"
msgstr "基本设置"
#: applications/luci-app-daed/root/usr/share/rpcd/acl.d/luci-app-daed.json:3
msgid "Grant access to daed configuration"
msgstr "授予访问 daed 配置的权限"
msgid "Dashboard"
msgstr "仪表板"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:76
msgid "Listening address"
msgstr "监听地址"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:28
msgid "Loading..."
msgstr "加载中..."
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:77
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:22
msgid "Log"
msgid "Logs"
msgstr "日志"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:46
msgid "Log file does not exist."
msgstr "日志文件不存在。"
msgid "Clear logs"
msgstr "清空日志"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:37
msgid "Log is empty."
msgstr "日志为空"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:81
msgid "Max log backups"
msgstr "最大日志备份"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:86
msgid "Max log size"
msgstr "最大日志大小"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:35
msgid "NOT RUNNING"
msgstr "未运行"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:32
msgid "Open Web Interface"
msgstr "打开 Web 界面"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:33
msgid "RUNNING"
msgstr "运行中"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:83
msgid "Refresh every %s seconds."
msgstr "每 %s 秒刷新。"
msgid "NOT RUNNING"
msgstr "未运行"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:69
msgctxt "scroll to top (the head) of the log file"
msgid "Scroll to head"
msgstr "滚动到顶部"
msgid "Collecting data..."
msgstr "收集数据..."
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:60
msgctxt "scroll to bottom (the tail) of the log file"
msgid "Scroll to tail"
msgstr "滚动到尾部"
msgid "Logfile retention count"
msgstr "日志文件保留数量"
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:14
msgid "Settings"
msgstr "设置"
msgid "Logfile Max Size (MB)"
msgstr "日志文件大小(MB)"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:82
msgid "The maximum number of old log files to retain."
msgstr "要保留的最大旧日志文件数量。"
msgid "Set the DAED listen address"
msgstr "设置监听地址"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:87
msgid "The maximum size in megabytes of the log file before it gets rotated."
msgstr "要保留的最大日志大小(单位:MB)。"
msgid "Dashboard Access Port"
msgstr "仪表板访问端口"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/log.js:50
msgid "Unknown error: %s"
msgstr "未知错误:%s"
msgid "Leave empty to use listen port"
msgstr "留空则使用监听端口"
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:33
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:35
#: applications/luci-app-daed/htdocs/luci-static/resources/view/daed/config.js:52
#: applications/luci-app-daed/root/usr/share/luci/menu.d/luci-app-daed.json:3
msgid "daed"
msgstr "daed"
msgid "For reverse proxy scenarios, leave empty to use the port from listen address"
msgstr "用于反向代理场景,留空则使用监听地址的端口"
msgid "DAED is not running"
msgstr "DAED 未运行"
msgid "Please start the DAED service first and try again"
msgstr "请先启动 DAED 服务后重试"
msgid "Enable Auto Subscribe Update"
msgstr "启用订阅自动更新"
msgid "Update Cycle"
msgstr "更新周期"
msgid "Update Time (Every Day)"
msgstr "更新时间(每天)"
msgid "Username"
msgstr "用户名"
msgid "Password"
msgstr "密码"
+31
View File
@@ -0,0 +1,31 @@
#!/bin/sh
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0
[ "$ACTION" = "ifupdate" ] && [ -z "$IFUPDATE_ADDRESSES" ] && [ -z "$IFUPDATE_DATA" ] && exit 0
UPTIME=$(cut -d. -f1 /proc/uptime 2>/dev/null)
[ -n "$UPTIME" ] && [ "$UPTIME" -lt 30 ] && exit 0
. /lib/functions/network.sh
network_find_wan6 NET_IF6
network_find_wan NET_IF
[ "$INTERFACE" != "$NET_IF6" ] && [ "$INTERFACE" != "$NET_IF" ] && exit 0
[ "$(uci -q get daed.config.enabled)" = "1" ] || exit 0
DEBOUNCE_FILE="/tmp/run/daed_hotplug_gen"
mkdir -p /tmp/run
my_gen="$$.$(date +%s)"
echo "$my_gen" > "$DEBOUNCE_FILE"
(
sleep 5
[ "$(cat "$DEBOUNCE_FILE" 2>/dev/null)" = "$my_gen" ] || exit 0
if /etc/init.d/daed running; then
/etc/init.d/daed restart
else
/etc/init.d/daed start
fi
) &
+93
View File
@@ -0,0 +1,93 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2023 Tianling Shen <cnsztl@immortalwrt.org>
USE_PROCD=0
START=98
CONF="daed"
PROG="/usr/bin/daed"
LOG="/var/log/daed/daed.log"
RESOLV_DAED="/tmp/resolv.conf.daed"
update_cron() {
local temp_cron="/tmp/root.cron"
if [ -f /etc/crontabs/root ]; then
grep -v '/etc/daed/daed_sub.sh' /etc/crontabs/root > "$temp_cron" 2>/dev/null
fi
: >> "$temp_cron"
local auto_update
auto_update=$(uci -q get daed.config.subscribe_auto_update)
if [ "$1" = "add" ] && [ "${auto_update:-0}" -eq 1 ]; then
local min=$((RANDOM % 60))
local hr=$(uci -q get daed.config.subscribe_update_day_time)
local wk=$(uci -q get daed.config.subscribe_update_week_time)
echo "$min ${hr:-*} * * ${wk:-*} /etc/daed/daed_sub.sh >/dev/null 2>&1" >> "$temp_cron"
fi
crontab "$temp_cron" 2>/dev/null
rm -f "$temp_cron"
}
hijack_resolv_conf() {
grep -q ' /tmp/resolv\.conf ' /proc/mounts && return 0
grep -E '^(search|domain) ' /tmp/resolv.conf > "$RESOLV_DAED" 2>/dev/null
local dns_list LOGICAL_WAN
. /lib/functions/network.sh
network_find_wan LOGICAL_WAN 2>/dev/null
if [ -n "$LOGICAL_WAN" ]; then
dns_list=$(ubus call "network.interface.$LOGICAL_WAN" status 2>/dev/null | \
jsonfilter -e '@["dns-server"][*]' 2>/dev/null)
fi
if [ -z "$dns_list" ] && [ -f "/tmp/resolv.conf.d/resolv.conf.auto" ]; then
dns_list=$(awk '/^nameserver/{print $2}' "/tmp/resolv.conf.d/resolv.conf.auto")
fi
[ -z "$dns_list" ] && dns_list="119.29.29.29 223.5.5.5"
for dns in $dns_list; do
echo "nameserver $dns" >> "$RESOLV_DAED"
done
mount --bind "$RESOLV_DAED" /tmp/resolv.conf
mount -o remount,ro,bind /tmp/resolv.conf
}
restore_resolv_conf() {
grep -q ' /tmp/resolv\.conf ' /proc/mounts || return 0
mount -o remount,rw,bind /tmp/resolv.conf 2>/dev/null
umount /tmp/resolv.conf 2>/dev/null
rm -f "$RESOLV_DAED"
}
start_service() {
[ -f "/etc/init.d/daed" ] && grep -q "DAE_LOCATION_ASSET" "/etc/init.d/daed" || sed -i '/run/i\ procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray"' "/etc/init.d/daed"
config_load "$CONF"
local enabled
config_get_bool enabled "config" "enabled" "0"
if [ "$enabled" -eq 0 ]; then
update_cron "remove"
restore_resolv_conf
return 1
fi
update_cron "add"
hijack_resolv_conf
}
stop_service() {
update_cron "remove"
restore_resolv_conf
}
service_triggers() {
procd_add_reload_trigger "$CONF"
}
reload_service() {
restart
}
@@ -1,29 +0,0 @@
{
"admin/services/daed": {
"title": "daed",
"order": 20,
"action": {
"type": "firstchild"
},
"depends": {
"acl": [ "luci-app-daed" ],
"uci": { "daed": true }
}
},
"admin/services/daed/config": {
"title": "Settings",
"order": 10,
"action": {
"type": "view",
"path": "daed/config"
}
},
"admin/services/daed/log": {
"title": "Log",
"order": 20,
"action": {
"type": "view",
"path": "daed/log"
}
}
}
@@ -1,13 +1,7 @@
{
"luci-app-daed": {
"description": "Grant access to daed configuration",
"description": "Grant UCI access for luci-app-daed",
"read": {
"file": {
"/var/log/daed/daed.log": [ "read" ]
},
"ubus": {
"service": [ "list" ]
},
"uci": [ "daed" ]
},
"write": {