update 2026-10-21 06:53:29

This commit is contained in:
action committed 2026-10-21 06:53:29 +08:00
1 parent ee55ecd1ef
commit f144cc6010
238 files changed
+301 -19729

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-daede
PKG_VERSION:=1.15
PKG_RELEASE:=9
PKG_RELEASE:=11
PKG_MAINTAINER:=kenzok8
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
@@ -35,6 +35,8 @@ const HEALTH_PATHS = {
btfDetached: '/usr/lib/debug/boot/vmlinux',
netns: '/run/netns/daens'
};
const INDEX_STATUS_PATH = '/tmp/luci-app-daede.idx.status';
let indexStartFailed = false;
const CSS = [
'.dd-up-wrap{padding:6px 0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif}',
@@ -122,10 +124,19 @@ function probeFile(path) {
function probePkg(pkg) {
return fs.exec('/usr/share/luci-app-daede/pkg-info.sh', [pkg]).then(function(res) {
const out = (res.stdout || '').trim().split('\t');
return { installed: out[0] || '', latest: out[1] || '' };
if (res.code !== 0) throw new Error('package probe failed');
const out = (res.stdout || '').replace(/[\r\n]+$/, '').split('\t');
return { installed: out[0] || '', latest: out[1] || '', state: out[2] || 'absent' };
}).catch(function() {
return { installed: '', latest: '' };
return { installed: '', latest: '', state: 'error' };
});
}
function probeIndex() {
if (indexStartFailed) return Promise.resolve('failed');
return L.resolveDefault(fs.read_direct(INDEX_STATUS_PATH, 'text'), '').then(function(out) {
const state = String(out).trim();
return state === 'success' || state === 'failed' ? state : 'running';
});
}
@@ -137,14 +148,16 @@ function stamp() {
return view.extend({
load: function() {
// background apk update so new versions show on next poll
fs.exec('/usr/share/luci-app-daede/refresh-index.sh', []).catch(function() {});
// The script starts a background refresh and returns after writing its state.
return Promise.all([
fs.exec('/usr/share/luci-app-daede/refresh-index.sh', []).then(function(res) {
indexStartFailed = res.code !== 0;
}).catch(function() { indexStartFailed = true; }),
backend.detectBackend(),
uci.load('daed').catch(function() {}),
uci.load('daede').catch(function() {})
]).then(function(r) {
return r[0];
return r[1];
});
},
@@ -342,6 +355,7 @@ return view.extend({
probes.push(probePkg(pkg));
});
probes.push(probePkg('luci-app-daede'));
probes.push(probeIndex());
if (ctx.backend.useNetns)
probes.push(probeFile(HEALTH_PATHS.netns));
@@ -354,7 +368,8 @@ return view.extend({
coreInfo[pkg] = r[pkgOffset + i];
});
const luci = r[pkgOffset + corePkgs.length];
const ns = r[pkgOffset + corePkgs.length + 1];
const indexState = r[pkgOffset + corePkgs.length + 1];
const ns = r[pkgOffset + corePkgs.length + 2];
// data rows
while (dataBody.firstChild) dataBody.removeChild(dataBody.firstChild);
@@ -391,26 +406,36 @@ return view.extend({
// a stale compile-jell build) must never be offered as an upgrade.
const cmp = (entry.r.installed && entry.r.latest)
? cmpVer(entry.r.latest, entry.r.installed) : null;
const updatable = cmp !== null && cmp > 0;
const updatable = indexState === 'success' && cmp !== null && cmp > 0;
let meta;
if (!entry.r.installed) {
meta = _('not installed via package manager');
meta = entry.r.state === 'manual' ? _('not installed via package manager')
: entry.r.state === 'foreign' ? _('unsupported package version')
: entry.r.state === 'error' ? _('package status unavailable') : _('Not installed');
btn.disabled = true;
btn.textContent = _('Unavailable');
} else if (indexState === 'failed') {
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('package index refresh failed');
btn.disabled = true;
} else if (indexState !== 'success') {
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('refreshing package indexes');
btn.disabled = true;
} else if (!entry.r.latest) {
// latest unknown (registry unreachable) - nothing to upgrade to
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('latest version unknown');
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('package not found in configured feeds');
btn.disabled = true;
} else if (updatable) {
meta = _('installed') + ': ' + entry.r.installed + ' → ' + _('latest') + ': ' + entry.r.latest;
} else if (cmp < 0) {
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('feed version older: %s').format(entry.r.latest);
btn.disabled = true;
} else {
// installed >= feed: already up to date (feed may even be older)
meta = _('installed') + ': ' + entry.r.installed + ' · ' + _('up to date');
btn.disabled = true;
}
const uncertain = entry.r.installed && (indexState !== 'success' || !entry.r.latest || cmp < 0);
pkgBody.appendChild(mkRow(
updatable ? '↑' : (entry.r.installed ? '✓' : '✗'),
updatable ? 'dd-up-new' : (entry.r.installed ? 'dd-up-ok' : 'dd-up-err'),
updatable ? '↑' : (uncertain ? '⚠' : (entry.r.installed ? '✓' : '✗')),
updatable ? 'dd-up-new' : (uncertain ? 'dd-up-warn' : (entry.r.installed ? 'dd-up-ok' : 'dd-up-err')),
entry.name,
meta,
btn
+18
View File
@@ -314,6 +314,24 @@ msgstr "已是最新"
msgid "not installed via package manager"
msgstr "非包管理器安装"
msgid "unsupported package version"
msgstr "已安装其他版本,无法在此升级"
msgid "package status unavailable"
msgstr "软件包状态读取失败"
msgid "package index refresh failed"
msgstr "软件源刷新失败,请检查网络和软件源"
msgid "refreshing package indexes"
msgstr "正在刷新软件源"
msgid "package not found in configured feeds"
msgstr "当前软件源中没有此包"
msgid "feed version older: %s"
msgstr "软件源版本较旧:%s"
msgid "Unavailable"
msgstr "不可用"
@@ -1,8 +1,8 @@
#!/bin/sh
# pkg-info.sh <package>
# Prints "<installed>\t<latest>" for the named package, where either field is
# empty when unknown. Used by the Updates view to decide whether to enable
# the [Upgrade] button.
# Prints "<installed>\t<latest>\t<state>" for the named package, where either
# version is empty when unknown. Used by the Updates view to decide whether to
# enable the [Upgrade] button.
PKG="$1"
case "$PKG" in
@@ -12,22 +12,26 @@ esac
installed=""
latest=""
state="absent"
if command -v apk >/dev/null 2>&1; then
if apk info -e "$PKG" >/dev/null 2>&1; then
state="managed"
installed=$(apk list -I "$PKG" 2>/dev/null | awk -v p="$PKG" '
$1 ~ "^" p "-" {
$1 ~ "^" p "-[0-9]" {
sub("^" p "-", "", $1);
print $1;
exit
}
')
[ -n "$installed" ] || state="error"
fi
# apk search treats ^ and $ as literal chars (not regex anchors), so the old
# `apk search "^pkg$"` matched nothing. Enumerate the exact-name package
# across all feeds via `apk list` and take the highest version. Restricting
# to "<pkg>-<digit>" avoids sibling names like <pkg>-geoip / luci-app-<pkg>.
latest=$(apk list "$PKG" 2>/dev/null | awk -v p="$PKG" '
# across configured feeds via `apk list -a` and take the highest version.
# The -a flag excludes locally installed packages that are absent from feeds.
# Restricting to "<pkg>-<digit>" avoids sibling names like <pkg>-geoip.
latest=$(apk list -a "$PKG" 2>/dev/null | awk -v p="$PKG" '
$1 ~ "^" p "-[0-9]" {
v = $1; sub("^" p "-", "", v);
print v
@@ -36,15 +40,22 @@ if command -v apk >/dev/null 2>&1; then
elif command -v opkg >/dev/null 2>&1; then
installed=$(opkg status "$PKG" 2>/dev/null | awk -F': ' '$1=="Version"{print $2; exit}')
latest=$(opkg info "$PKG" 2>/dev/null | awk -F': ' '$1=="Version"{print $2; exit}')
[ -n "$installed" ] && state="managed"
fi
case "$PKG" in
dae|daed)
case "$installed" in
20[0-9][0-9].[0-9]*) ;;
*) installed="" ;;
*) [ -n "$installed" ] && state="foreign"; installed="" ;;
esac
;;
esac
printf '%s\t%s\n' "$installed" "$latest"
if [ "$state" = "absent" ]; then
case "$PKG" in
dae|daed) [ -x "/usr/bin/$PKG" ] && state="manual" ;;
esac
fi
printf '%s\t%s\t%s\n' "$installed" "$latest" "$state"
@@ -2,20 +2,39 @@
# Background apk/opkg update for the Updates view. Returns at once; throttled.
LOCK=/tmp/luci-app-daede.idx.lock
STATUS=/tmp/luci-app-daede.idx.status
LOG=/tmp/luci-app-daede.idx.log
if [ -f "$LOCK" ]; then
write_status() {
printf '%s\n' "$1" > "${STATUS}.$$" && mv "${STATUS}.$$" "$STATUS"
}
if [ -f "$LOCK" ] && [ -f "$STATUS" ]; then
mtime=$(date -r "$LOCK" +%s 2>/dev/null || echo 0)
[ "$(( $(date +%s) - mtime ))" -lt 90 ] && exit 0
fi
: > "$LOCK"
write_status running
(
# -n: skip if a package op holds the shared apk lock (no need to refresh then)
flock -n 9 || exit 0
umask 077
# Wait for package upgrades before refreshing the same apk database.
if command -v apk >/dev/null 2>&1; then
flock -n /tmp/luci-app-daede.apk.lock apk update
flock /tmp/luci-app-daede.apk.lock apk update > "$LOG" 2>&1
rc=$?
elif command -v opkg >/dev/null 2>&1; then
opkg update
opkg update > "$LOG" 2>&1
rc=$?
else
printf '%s\n' 'No supported package manager' > "$LOG"
rc=127
fi
) >/dev/null 2>&1 </dev/null &
if [ "$rc" -eq 0 ]; then
write_status success
else
write_status failed
fi
) 9>/tmp/luci-app-daede.idx.run.lock >/dev/null 2>&1 </dev/null &
exit 0
@@ -50,15 +50,27 @@ fi
if command -v apk >/dev/null 2>&1; then
# shared apk lock with the bg index refresh (avoid "Unable to lock database")
(
flock 9
apk update 2>&1
ver=$(apk list "$PKG" 2>/dev/null | awk -v p="$PKG" '$1 ~ "^" p "-[0-9]" { v=$1; sub("^" p "-", "", v); print v }' | sort -V | tail -1)
flock 9 || exit 1
if ! apk info -e "$PKG" >/dev/null 2>&1; then
echo "result: $PKG 未通过包管理器安装,不能在线升级"
exit 1
fi
if ! apk update 2>&1; then
echo "result: 软件源刷新失败,请检查网络和软件源配置"
exit 1
fi
ver=$(apk list -a "$PKG" 2>/dev/null | awk -v p="$PKG" '$1 ~ "^" p "-[0-9]" { v=$1; sub("^" p "-", "", v); print v }' | sort -V | tail -1)
if [ -n "$ver" ]; then
constraint="$PKG=$ver"
else
echo "result: 软件源中没有找到 $PKG,请检查网络或软件源配置"
exit 1
fi
installed=$(apk list -I "$PKG" 2>/dev/null | awk -v p="$PKG" '$1 ~ "^" p "-[0-9]" { v=$1; sub("^" p "-", "", v); print v; exit }')
if [ -n "$installed" ] && [ "$(printf '%s\n%s\n' "$ver" "$installed" | sort -V | tail -1)" = "$installed" ]; then
echo "result: $PKG 已安装版本不低于软件源版本,无需升级"
exit 2
fi
echo "--- apk add -s $constraint ---"
if ! apk add -s "$constraint" 2>&1; then
@@ -66,14 +78,19 @@ fi
fi
echo "--- apk add $constraint ---"
apk add "$constraint" 2>&1
add_rc=$?
[ "$add_rc" -eq 0 ] || exit 1
if ! apk list -I "$PKG" 2>/dev/null | awk -v p="$PKG" -v v="$ver" '$1 == p "-" v { found = 1 } END { exit !found }'; then
echo "result: $PKG was not upgraded to $ver"
exit 1
fi
exit 0
) 9>/tmp/luci-app-daede.apk.lock
rc=$?
if [ "$rc" != 0 ]; then
if [ "$rc" = 2 ]; then
:
elif [ "$rc" != 0 ]; then
:
elif ! apk list --installed 2>/dev/null | grep -q "^${PKG}-"; then
echo "result: $PKG is not installed"
rc=1
elif apk list -u 2>/dev/null | grep -q "^${PKG}-"; then
echo "result: $PKG still has a pending upgrade"
rc=1
@@ -83,16 +100,26 @@ fi
fi
elif command -v opkg >/dev/null 2>&1; then
echo "--- opkg update ---"
opkg update 2>&1
echo "--- opkg upgrade $PKG ---"
opkg upgrade "$PKG" 2>&1
rc=$?
if opkg update 2>&1; then
echo "--- opkg upgrade $PKG ---"
opkg upgrade "$PKG" 2>&1
rc=$?
else
echo "result: 软件源刷新失败,请检查网络和软件源配置"
rc=1
fi
else
echo "no package manager found"
exit 3
rc=3
fi
if [ "$rc" = 0 ]; then echo "$(date '+%F %T') ✓ 完成"; else echo "$(date '+%F %T') ✗ 失败 (rc=$rc)"; fi
if [ "$rc" = 0 ]; then
echo "$(date '+%F %T') ✓ 完成"
elif [ "$rc" = 2 ]; then
echo "$(date '+%F %T') ✓ 无需升级"
else
echo "$(date '+%F %T') ✗ 失败 (rc=$rc)"
fi
# luci-app-daede upgrade replaces ACL JSON — reload rpcd so changes apply.
if [ "$PKG" = "luci-app-daede" ] && [ "$rc" = "0" ]; then
@@ -20,6 +20,7 @@
"/tmp/luci-app-daede.pkg-dae.log": [ "read" ],
"/tmp/luci-app-daede.pkg-daed.log": [ "read" ],
"/tmp/luci-app-daede.pkg-luci-app-daede.log": [ "read" ],
"/tmp/luci-app-daede.idx.status": [ "read" ],
"/tmp/luci-app-daede.backup.log": [ "read" ],
"/bin/pidof dae": [ "exec" ],
"/bin/pidof daed": [ "exec" ],