mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-01 16:44:23 +08:00
🍕 Sync 2026-10-24 11:03:07
This commit is contained in:
1 parent
19d56ae59c
commit
9886197604
8 files changed
+292
-15
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=cpulimit
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=1.0.2
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/denji/cpulimit/tar.gz/$(PKG_VERSION)?
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=filebrowser-q
|
||||
PKG_VERSION:=2.0.1-stable
|
||||
PKG_RELEASE:=10
|
||||
PKG_VERSION:=2.0.2-stable
|
||||
PKG_RELEASE:=11
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/gtsteffaniak/filebrowser/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-open-box
|
||||
PKG_VERSION:=0.1.354
|
||||
PKG_RELEASE:=43
|
||||
PKG_VERSION:=0.1.356
|
||||
PKG_RELEASE:=44
|
||||
|
||||
PKG_MAINTAINER:=liandu2024
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-trafficctl
|
||||
PKG_VERSION:=1.24.0
|
||||
PKG_RELEASE:=15
|
||||
PKG_VERSION:=1.25.0
|
||||
PKG_RELEASE:=16
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_MAINTAINER:=Denis Iusupov <yusdyr@gmail.com>
|
||||
|
||||
@@ -96,6 +96,15 @@ config history 'history'
|
||||
# How many FINISHED periods to retain. The current one is never a
|
||||
# retention candidate.
|
||||
option keep '12'
|
||||
# Also accumulate per-INTERFACE totals (#102), in their own file per
|
||||
# period. A second series rather than a breakdown of the device one: these
|
||||
# are the kernel's interface counters, so they include the router's own
|
||||
# traffic and broadcast, they legitimately disagree with the sum over
|
||||
# devices, and under flow offloading they are the MORE accurate of the two
|
||||
# because they come from the driver rather than from conntrack. They also
|
||||
# answer what the device series cannot: how much went out of wan1 versus
|
||||
# wan2. Off is reasonable on a single-WAN router.
|
||||
option interfaces '1'
|
||||
|
||||
config logging 'logging'
|
||||
option enabled '1'
|
||||
|
||||
@@ -73,9 +73,10 @@ list)
|
||||
printf '"activity_log":{"lines":"int"},'
|
||||
printf '"history_status":{},'
|
||||
printf '"history_read":{"period":"str","to":"str"},'
|
||||
printf '"history_read_ifaces":{"period":"str","to":"str"},'
|
||||
printf '"history_periods":{},'
|
||||
printf '"history_config_get":{},'
|
||||
printf '"history_config_set":{"enabled":"bool","dir":"str","period":"str","interval":"int","sample_interval":"int","keep":"int"},'
|
||||
printf '"history_config_set":{"enabled":"bool","dir":"str","period":"str","interval":"int","sample_interval":"int","keep":"int","interfaces":"bool"},'
|
||||
printf '"history_flush":{},'
|
||||
printf '"version":{}'
|
||||
printf '}'
|
||||
@@ -633,6 +634,26 @@ call)
|
||||
$SCRIPTS/trafficctl-history.sh read "$hp" "$ht"
|
||||
printf '}'
|
||||
;;
|
||||
history_read_ifaces)
|
||||
read -r input
|
||||
# Same shape check as history_read: these ids never reach a path, but
|
||||
# they come from the network, so a malformed one is rejected rather
|
||||
# than passed through to match nothing.
|
||||
hp=$(echo "$input" | jsonfilter -e '@.period' 2>/dev/null)
|
||||
ht=$(echo "$input" | jsonfilter -e '@.to' 2>/dev/null)
|
||||
for v in "$hp" "$ht"; do
|
||||
[ -z "$v" ] && continue
|
||||
case "$v" in
|
||||
[0-9][0-9][0-9][0-9]-[0-9][0-9]) ;;
|
||||
[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ;;
|
||||
[0-9][0-9][0-9][0-9]-W[0-9][0-9]) ;;
|
||||
*) echo '{"result":[]}'; exit 0 ;;
|
||||
esac
|
||||
done
|
||||
printf '{"result":'
|
||||
$SCRIPTS/trafficctl-history.sh read-ifaces "$hp" "$ht"
|
||||
printf '}'
|
||||
;;
|
||||
history_config_get)
|
||||
printf '{"result":'
|
||||
$SCRIPTS/trafficctl-history.sh status
|
||||
@@ -673,6 +694,10 @@ call)
|
||||
if [ -n "$val" ]; then
|
||||
uci set "trafficctl.history.enabled=$([ "$val" = "true" ] && echo 1 || echo 0)"
|
||||
fi
|
||||
val=$(echo "$input" | jsonfilter -e '@.interfaces' 2>/dev/null)
|
||||
if [ -n "$val" ]; then
|
||||
uci set "trafficctl.history.interfaces=$([ "$val" = "true" ] && echo 1 || echo 0)"
|
||||
fi
|
||||
tctl_commit
|
||||
# The keeper re-reads the intervals and the directory on every tick,
|
||||
# but it has to be RUNNING to do that — switching history on for the
|
||||
|
||||
@@ -93,6 +93,7 @@ ERRFILE="/tmp/trafficctl_history.err"
|
||||
STAMP="/tmp/trafficctl_history.stamp"
|
||||
LOCKD="/tmp/trafficctl_history.lock.d"
|
||||
TOTALS_STATE="/tmp/trafficctl_totals.state"
|
||||
IFCURSOR="/tmp/trafficctl_history.ifcursor"
|
||||
|
||||
# Row layout, tab-separated:
|
||||
# key mac ip name rx tx tcp udp first_seen last_seen degraded
|
||||
@@ -211,6 +212,23 @@ hist_period_id() {
|
||||
|
||||
hist_file() { printf '%s/%s.tsv\n' "$(hist_dir)" "$1"; }
|
||||
|
||||
# Interface totals live in their OWN file per period, not as an extra record
|
||||
# type in the device file (#102).
|
||||
#
|
||||
# The issue proposed a type column. A separate file is better for the reason
|
||||
# that matters here: hist_read emits every row it finds as a device, so an
|
||||
# interface row sharing the file would be reported AS a device by any reader
|
||||
# that predates the change — including the History tab as shipped in v1.22.0.
|
||||
# A file the old reader never opens cannot be misread.
|
||||
hist_iffile() { printf '%s/%s.if.tsv\n' "$(hist_dir)" "$1"; }
|
||||
|
||||
# Per-interface accumulation can be turned off on its own: on a single-WAN
|
||||
# router it is a handful of rows nobody reads, and the point of the feature is
|
||||
# multi-WAN.
|
||||
hist_ifaces_enabled() {
|
||||
[ "$(uci -q get trafficctl.history.interfaces 2>/dev/null)" != "0" ]
|
||||
}
|
||||
|
||||
hist_err_set() {
|
||||
printf '%s\t%s\n' "$(date +%s)" "$1" > "$ERRFILE" 2>/dev/null
|
||||
tctl_log config "history: $1" 2>/dev/null || true
|
||||
@@ -546,10 +564,220 @@ hist_flush() {
|
||||
printf '%s\n' "$now" > "$STAMP" 2>/dev/null
|
||||
hist_err_clear
|
||||
|
||||
# Only after the device file is safely in place. A failure here is not a
|
||||
# failure of the flush: the interface series is additive, and losing one
|
||||
# interval of it must not make the caller think the device totals did not
|
||||
# land.
|
||||
hist_if_flush || hist_err_set "interface totals could not be written"
|
||||
|
||||
|
||||
printf '{"ok":true,"period":"%s","devices":%s,"at":%s}\n' \
|
||||
"$pid" "$(grep -vc '^#' "$file" 2>/dev/null || echo 0)" "$now"
|
||||
}
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# Interface totals (#102)
|
||||
#
|
||||
# A SECOND SERIES, not a breakdown of the device one, and the distinction is
|
||||
# not pedantry:
|
||||
#
|
||||
# * these bytes are the kernel's own interface counters, read by
|
||||
# trafficctl-ifaces.sh out of /proc/net/dev. They include the router's own
|
||||
# traffic, broadcast, and everything per-device accounting cannot
|
||||
# attribute, so they legitimately DISAGREE with the sum over devices.
|
||||
# * under flow offloading they are the MORE trustworthy of the two, because
|
||||
# they come from the driver rather than from conntrack — exactly inverted
|
||||
# from the device series, where offload is what degrades accuracy. Hence
|
||||
# hist_if_accuracy below, which must not inherit the device verdict.
|
||||
# * they answer a question the device series cannot: how much went out of
|
||||
# wan1 versus wan2 this month. A device's bytes carry no egress interface.
|
||||
#
|
||||
# rx/tx are relative to the INTERFACE, not to a client: rx on the WAN device
|
||||
# is download, rx on br-lan is what the LAN sent upstream. Stored as read,
|
||||
# with the role, so a consumer can label them rather than guess.
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# Interfaces whose bytes are already counted somewhere else, and would
|
||||
# double-count if recorded:
|
||||
# enslaved — a bridge port; its traffic is in the bridge's own counters
|
||||
# lo — loopback
|
||||
# the IFB — a mirror of LAN ingress that the shaper creates, so every byte
|
||||
# on it is a byte already counted on the device it mirrors
|
||||
hist_if_skip() {
|
||||
local dev="$1" enslaved="$2" ifb
|
||||
[ "$dev" = "lo" ] && return 0
|
||||
[ "$enslaved" = "true" ] && return 0
|
||||
ifb=$(uci -q get trafficctl.main.shape_ifb 2>/dev/null)
|
||||
[ -n "$ifb" ] && [ "$dev" = "$ifb" ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
# What the interface series is worth. NOT the device verdict: an interface
|
||||
# counter comes from the driver, so uncountered offload — the thing that makes
|
||||
# the device totals a lower bound — does not touch it. Reporting "degraded"
|
||||
# here would be its own kind of wrong.
|
||||
hist_if_accuracy() {
|
||||
printf 'exact\n'
|
||||
}
|
||||
|
||||
# Fold the interface counters into the current period, exactly as the device
|
||||
# flush does: growth against a tmpfs cursor, and a live value below the cursor
|
||||
# means the counter restarted rather than that traffic went backwards.
|
||||
#
|
||||
# An interface counter restarting is NOT an edge case here. It happens every
|
||||
# time the link goes down, which on the multi-WAN box this feature is for is
|
||||
# routine — so a flap costs one sampling interval instead of corrupting the
|
||||
# month.
|
||||
hist_if_flush() {
|
||||
local dir pid file tmp now sample rc=0
|
||||
hist_ifaces_enabled || return 0
|
||||
dir=$(hist_dir)
|
||||
pid=$(hist_period_id)
|
||||
file=$(hist_iffile "$pid")
|
||||
now=$(date +%s)
|
||||
sample="/tmp/.trafficctl_history.ifsample.$$"
|
||||
tmp="$dir/.history-if.$pid.$$"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -f '$sample' '$tmp'" EXIT INT TERM
|
||||
|
||||
/usr/local/bin/trafficctl-ifaces.sh 2>/dev/null \
|
||||
| sed 's/},{/}\n{/g' > "$sample"
|
||||
[ -s "$sample" ] || return 0
|
||||
|
||||
awk -v sample="$sample" -v cursor="$IFCURSOR" -v out="$tmp" -v store="$file" \
|
||||
-v now="$now" -v ifb="$(uci -q get trafficctl.main.shape_ifb 2>/dev/null)" '
|
||||
function num(line, key, re, seg) {
|
||||
re = "\"" key "\"[ \t]*:[ \t]*"
|
||||
if (!match(line, re)) return -1
|
||||
seg = substr(line, RSTART + RLENGTH)
|
||||
if (!match(seg, /^[0-9]+/)) return -1
|
||||
return substr(seg, RSTART, RLENGTH) + 0
|
||||
}
|
||||
function str(line, key, re, seg) {
|
||||
re = "\"" key "\"[ \t]*:[ \t]*\""
|
||||
if (!match(line, re)) return ""
|
||||
seg = substr(line, RSTART + RLENGTH)
|
||||
if (!match(seg, /"/)) return ""
|
||||
return substr(seg, 1, RSTART - 1)
|
||||
}
|
||||
BEGIN {
|
||||
FS = "\t"
|
||||
cf = cursor ".new"
|
||||
printf "" > cf
|
||||
while ((getline l < cursor) > 0) {
|
||||
n = split(l, f, "\t")
|
||||
if (n < 3) continue
|
||||
crx[f[1]] = f[2] + 0; ctx[f[1]] = f[3] + 0
|
||||
seen[f[1]] = 1
|
||||
}
|
||||
close(cursor)
|
||||
while ((getline l < store) > 0) {
|
||||
if (l ~ /^#/) continue
|
||||
n = split(l, f, "\t")
|
||||
if (n < 7) continue
|
||||
d = f[1]
|
||||
order[++norder] = d
|
||||
role[d] = f[2]; label[d] = f[3]
|
||||
rrx[d] = f[4] + 0; rtx[d] = f[5] + 0
|
||||
first[d] = f[6] + 0; last[d] = f[7] + 0
|
||||
have[d] = 1
|
||||
}
|
||||
close(store)
|
||||
|
||||
while ((getline line < sample) > 0) {
|
||||
if (line !~ /"dev":"/) continue
|
||||
d = str(line, "dev")
|
||||
if (d == "") continue
|
||||
if (d == "lo") continue
|
||||
if (index(line, "\"enslaved\":true") > 0) continue
|
||||
if (ifb != "" && d == ifb) continue
|
||||
lrx = num(line, "rx_bytes"); if (lrx < 0) continue
|
||||
ltx = num(line, "tx_bytes"); if (ltx < 0) continue
|
||||
|
||||
drx = lrx; dtx = ltx
|
||||
if (seen[d]) {
|
||||
drx = 0; dtx = 0
|
||||
if (lrx >= crx[d]) drx = lrx - crx[d]
|
||||
if (ltx >= ctx[d]) dtx = ltx - ctx[d]
|
||||
}
|
||||
if (!(d in have)) {
|
||||
order[++norder] = d
|
||||
have[d] = 1
|
||||
first[d] = now
|
||||
rrx[d] = 0; rtx[d] = 0
|
||||
}
|
||||
rrx[d] += drx; rtx[d] += dtx
|
||||
r = str(line, "role"); if (r != "") role[d] = r
|
||||
lb = str(line, "label"); if (lb != "") label[d] = lb
|
||||
if (drx > 0 || dtx > 0) last[d] = now
|
||||
else if (last[d] == 0) last[d] = now
|
||||
ncrx[d] = lrx; nctx[d] = ltx
|
||||
written[d] = 1
|
||||
}
|
||||
close(sample)
|
||||
|
||||
printf "# trafficctl-history-if 1\n" > out
|
||||
for (i = 1; i <= norder; i++) {
|
||||
d = order[i]
|
||||
if (!(d in have) || emitted[d]) continue
|
||||
emitted[d] = 1
|
||||
rl = role[d]; if (rl == "") rl = "?"
|
||||
lb = label[d]; if (lb == "") lb = "-"
|
||||
printf "%s\t%s\t%s\t%.0f\t%.0f\t%d\t%d\n", \
|
||||
d, rl, lb, rrx[d], rtx[d], first[d], last[d] > out
|
||||
}
|
||||
close(out)
|
||||
|
||||
for (d in seen) if (!(d in written))
|
||||
printf "%s\t%.0f\t%.0f\n", d, crx[d], ctx[d] > cf
|
||||
for (d in written)
|
||||
printf "%s\t%.0f\t%.0f\n", d, ncrx[d], nctx[d] > cf
|
||||
close(cf)
|
||||
}' </dev/null || rc=1
|
||||
|
||||
[ "$rc" = 0 ] && [ -f "$tmp" ] || return 1
|
||||
hist_guard mv "$tmp" "$file" 2>/dev/null || return 1
|
||||
mv "$IFCURSOR.new" "$IFCURSOR" 2>/dev/null || true
|
||||
return 0
|
||||
}
|
||||
|
||||
hist_if_read() {
|
||||
local dir from to files f p
|
||||
dir=$(hist_dir)
|
||||
from="$1"; to="$2"
|
||||
[ -z "$from" ] && from=$(hist_period_id)
|
||||
[ -z "$to" ] && to="$from"
|
||||
files=""
|
||||
for f in "$dir"/*.if.tsv; do
|
||||
[ -f "$f" ] || continue
|
||||
p=$(basename "$f" .if.tsv)
|
||||
[ "$p" \< "$from" ] && continue
|
||||
[ "$to" \< "$p" ] && continue
|
||||
files="$files $f"
|
||||
done
|
||||
# shellcheck disable=SC2086 # deliberate splitting over the file list
|
||||
awk -F'\t' '
|
||||
/^#/ { next }
|
||||
NF >= 7 {
|
||||
d = $1
|
||||
if (!(d in seen)) { order[++n] = d; seen[d] = 1; first[d] = $6 }
|
||||
role[d] = $2; label[d] = $3
|
||||
rx[d] += $4; tx[d] += $5
|
||||
if ($6 + 0 < first[d] + 0) first[d] = $6
|
||||
if ($7 + 0 > last[d] + 0) last[d] = $7
|
||||
}
|
||||
END {
|
||||
printf "["
|
||||
for (i = 1; i <= n; i++) {
|
||||
d = order[i]
|
||||
if (i > 1) printf ","
|
||||
printf "{\"dev\":\"%s\",\"role\":\"%s\",\"label\":\"%s\",\"bytes_in\":%.0f,\"bytes_out\":%.0f,\"first_seen\":%d,\"last_seen\":%d}", \
|
||||
d, role[d], label[d], rx[d], tx[d], first[d], last[d]
|
||||
}
|
||||
printf "]\n"
|
||||
}' $files </dev/null 2>/dev/null || printf '[]\n'
|
||||
}
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# read / periods
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
@@ -563,6 +791,9 @@ hist_read() {
|
||||
files=""
|
||||
for f in "$dir"/*.tsv; do
|
||||
[ -f "$f" ] || continue
|
||||
# The interface totals are a separate series in their own file; reading
|
||||
# them here would report an interface as a device.
|
||||
case "$f" in *.if.tsv) continue ;; esac
|
||||
p=$(basename "$f" .tsv)
|
||||
# String comparison is the right one here: every period id this script
|
||||
# writes is fixed-width and zero-padded, so lexical order IS
|
||||
@@ -614,6 +845,9 @@ hist_periods() {
|
||||
n=0
|
||||
for f in "$dir"/*.tsv; do
|
||||
[ -f "$f" ] || continue
|
||||
# Skip the interface companion: a period is listed once, by its device
|
||||
# file, or "2026-10" and "2026-10.if" would both appear as periods.
|
||||
case "$f" in *.if.tsv) continue ;; esac
|
||||
p=$(basename "$f" .tsv)
|
||||
[ "$n" -gt 0 ] && printf ','
|
||||
printf '{"period":"%s","devices":%s,"bytes":%s}' \
|
||||
@@ -633,13 +867,20 @@ hist_prune() {
|
||||
# The current period is never a retention candidate — it is still being
|
||||
# written to, and "keep 1" must not mean "delete the data you are
|
||||
# collecting right now".
|
||||
# A PERIOD is the unit of retention, and a period is now two files: the
|
||||
# device totals and the interface totals (#102). Listing *.tsv and
|
||||
# stripping .tsv would turn "2026-10.if.tsv" into a period called
|
||||
# "2026-10.if" — never equal to the current period id, so it would be
|
||||
# pruned as if it were ancient history while its device file survived.
|
||||
# Enumerate periods from the device files only, then drop both.
|
||||
# shellcheck disable=SC2046 # deliberate splitting: one word per period id
|
||||
set -- $(find "$dir" -name '*.tsv' -type f 2>/dev/null \
|
||||
| sed 's|.*/||; s|\.tsv$||' | grep -vxF "$pid" | sort)
|
||||
| sed 's|.*/||' | grep -v '\.if\.tsv$' | sed 's|\.tsv$||' \
|
||||
| grep -vxF "$pid" | sort)
|
||||
total=$#
|
||||
while [ "$total" -gt "$keep" ] && [ "$#" -gt 0 ]; do
|
||||
f="$dir/$1.tsv"
|
||||
rm -f "$f" 2>/dev/null && dropped=$((dropped + 1))
|
||||
rm -f "$dir/$1.tsv" 2>/dev/null && dropped=$((dropped + 1))
|
||||
rm -f "$dir/$1.if.tsv" 2>/dev/null
|
||||
total=$((total - 1))
|
||||
shift
|
||||
done
|
||||
@@ -686,10 +927,11 @@ hist_status() {
|
||||
fi
|
||||
w=false
|
||||
[ -d "$dir" ] && [ -w "$dir" ] && w=true
|
||||
printf '{"enabled":%s,"dir":"%s","writable":%s,"period":"%s","period_kind":"%s","interval":%s,"sample_interval":%s,"keep":%s,"format":%s,"last_flush":%s,"accuracy":"%s","offload":"%s","error":"%s","error_at":%s}\n' \
|
||||
printf '{"enabled":%s,"dir":"%s","writable":%s,"period":"%s","period_kind":"%s","interval":%s,"sample_interval":%s,"keep":%s,"format":%s,"last_flush":%s,"accuracy":"%s","offload":"%s","interfaces":%s,"iface_accuracy":"%s","error":"%s","error_at":%s}\n' \
|
||||
"$en" "$dir" "$w" "$pid" "$(hist_period_kind)" \
|
||||
"$(hist_interval)" "$(hist_sample_interval)" "$(hist_keep)" "$FORMAT" "$last" \
|
||||
"$(hist_accuracy)" "$(tctl_get_offload_mode 2>/dev/null)" \
|
||||
"$(hist_ifaces_enabled && echo true || echo false)" "$(hist_if_accuracy)" \
|
||||
"$(printf '%s' "$err" | tr -d '\042\134')" "$errat"
|
||||
}
|
||||
|
||||
@@ -743,11 +985,12 @@ case "$1" in
|
||||
# than a second copy of the rule that can drift away from it.
|
||||
validate-dir) hist_validate_dir "${2%/}" ;;
|
||||
read) hist_read "$2" "$3" ;;
|
||||
read-ifaces) hist_if_read "$2" "$3" ;;
|
||||
periods) hist_periods ;;
|
||||
prune) hist_prune ;;
|
||||
status) hist_status ;;
|
||||
*)
|
||||
printf 'Usage: %s {sample|flush|keeper|validate-dir <path>|read [period [to]]|periods|prune|status}\n' "$0" >&2
|
||||
printf 'Usage: %s {sample|flush|keeper|validate-dir <path>|read [period [to]]|read-ifaces [period [to]]|periods|prune|status}\n' "$0" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -11,7 +11,7 @@
|
||||
"shape_status",
|
||||
"config_get", "telegram_config_get",
|
||||
"logging_config_get", "newdevice_config_get",
|
||||
"history_status", "history_read", "history_periods",
|
||||
"history_status", "history_read", "history_read_ifaces", "history_periods",
|
||||
"history_config_get"
|
||||
],
|
||||
"file": [ "read" ]
|
||||
|
||||
Reference in new issue
Block a user