├── README.md
├── homebox
├── files
│ ├── homebox.config
│ ├── homebox.uci-default
│ └── homebox.init
└── Makefile
├── luci-app-cpufreq
├── root
│ └── etc
│ │ ├── config
│ │ ├── tuning
│ │ ├── tuning_boot
│ │ ├── tuning_net
│ │ └── cpufreq
│ │ ├── uci-defaults
│ │ ├── 21_tuning
│ │ ├── 21_cpufreq
│ │ └── 21_tuning_net
│ │ └── init.d
│ │ ├── tuning
│ │ ├── cpufreq
│ │ ├── tuning_net
│ │ └── await_fstab
├── luasrc
│ ├── view
│ │ └── cpufreq
│ │ │ ├── sb_info.zh-cn.htm
│ │ │ ├── sb_guide.zh-cn.htm
│ │ │ ├── sb_guide.htm
│ │ │ ├── sb_info.htm
│ │ │ ├── cpuinfo.htm
│ │ │ └── sandbox.htm
│ ├── model
│ │ └── cbi
│ │ │ └── cpufreq
│ │ │ ├── samba.lua
│ │ │ ├── net.lua
│ │ │ ├── kmods.lua
│ │ │ ├── ipk.lua
│ │ │ ├── main.lua
│ │ │ ├── boot.lua
│ │ │ └── cmdline.lua
│ └── controller
│ │ └── admin
│ │ └── cpufreq.lua
├── Makefile
└── po
│ ├── en
│ └── cpufreq.po
│ ├── templates
│ └── cpufreq.pot
│ └── zh-cn
│ └── cpufreq.po
├── luci-app-homebox
├── luasrc
│ ├── view
│ │ ├── admin_status
│ │ │ └── index
│ │ │ │ └── homebox.htm
│ │ └── homebox_status.htm
│ ├── model
│ │ └── cbi
│ │ │ └── homebox.lua
│ └── controller
│ │ └── homebox.lua
├── root
│ └── etc
│ │ └── uci-defaults
│ │ └── 50_luci-homebox
├── Makefile
└── po
│ └── zh-cn
│ └── homebox.po
├── luci-app-mergerfs
├── root
│ └── usr
│ │ └── share
│ │ ├── ucitrack
│ │ └── luci-app-mergerfs.json
│ │ ├── luci
│ │ └── menu.d
│ │ │ └── luci-app-mergerfs.json
│ │ └── rpcd
│ │ └── acl.d
│ │ └── luci-app-mergerfs.json
├── Makefile
├── po
│ └── zh_Hans
│ │ └── mergerfs.po
└── htdocs
│ └── luci-static
│ └── resources
│ └── view
│ └── mergerfs.js
├── luci-app-fan
├── root
│ ├── etc
│ │ ├── config
│ │ │ └── luci-fan
│ │ ├── uci-defaults
│ │ │ └── luci-fan
│ │ └── init.d
│ │ │ └── luci-fan
│ └── usr
│ │ └── libexec
│ │ └── fan-control
├── Makefile
├── luasrc
│ ├── view
│ │ └── luci-fan.htm
│ ├── controller
│ │ └── admin
│ │ │ └── luci-fan.lua
│ └── model
│ │ └── cbi
│ │ └── luci-fan.lua
└── po
│ ├── templates
│ └── luci-fan.pot
│ └── zh-cn
│ └── luci-fan.po
├── luci-alias.mk
├── luci-lib-mac-vendor
├── src
│ └── Makefile
└── Makefile
├── mergerfs
├── files
│ ├── mergerfs.config
│ ├── mergerfs.fstab
│ └── mergerfs.init
├── patches
│ ├── 002-fix-install.patch
│ ├── 003-fix-build-non-x86-target.patch
│ └── 001-fix-lto.patch
└── Makefile
├── luci-app-tasks
├── luasrc
│ ├── controller
│ │ └── tasks-app.lua
│ ├── view
│ │ └── tasks
│ │ │ └── all.htm
│ └── model
│ │ └── cbi
│ │ └── tasks
│ │ └── all.lua
├── Makefile
└── po
│ └── zh-cn
│ └── tasks.po
├── ssd1306
├── test.sh
└── Makefile
├── LICENSE
├── nvtop
└── Makefile
└── duperemove
└── Makefile
/README.md:
--------------------------------------------------------------------------------
1 | # openwrt-apps
2 | app for openwrt luci
3 |
--------------------------------------------------------------------------------
/homebox/files/homebox.config:
--------------------------------------------------------------------------------
1 | config homebox
2 | option 'enabled' '0'
3 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/config/tuning:
--------------------------------------------------------------------------------
1 | config ipk
2 | option mirror 'disable'
3 |
--------------------------------------------------------------------------------
/luci-app-homebox/luasrc/view/admin_status/index/homebox.htm:
--------------------------------------------------------------------------------
1 | <%+homebox_status%>
2 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/config/tuning_boot:
--------------------------------------------------------------------------------
1 | config fstab_delay
2 | option enabled '0'
3 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/config/tuning_net:
--------------------------------------------------------------------------------
1 | config hw_acct
2 | option wan_acct '1'
3 | option hw_pppoe '1'
--------------------------------------------------------------------------------
/luci-app-homebox/root/etc/uci-defaults/50_luci-homebox:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -f /tmp/luci-indexcache
4 | exit 0
5 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/config/cpufreq:
--------------------------------------------------------------------------------
1 | config cpufreq
2 | # option governor 'ondemand'
3 | # option speed '1000000'
4 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/root/usr/share/ucitrack/luci-app-mergerfs.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": "mergerfs",
3 | "init": "mergerfs"
4 | }
5 |
--------------------------------------------------------------------------------
/luci-app-fan/root/etc/config/luci-fan:
--------------------------------------------------------------------------------
1 | config luci-fan
2 | option enabled 0
3 | # option on_temp 55
4 | # option off_temp 50
--------------------------------------------------------------------------------
/homebox/files/homebox.uci-default:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@homebox[-1]
5 | add ucitrack homebox
6 | set ucitrack.@homebox[-1].init=homebox
7 | commit ucitrack
8 | EOF
9 |
10 | exit 0
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/uci-defaults/21_tuning:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@tuning[-1]
5 | add ucitrack tuning
6 | set ucitrack.@tuning[-1].init=tuning
7 | commit ucitrack
8 | EOF
9 |
10 | exit 0
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/sb_info.zh-cn.htm:
--------------------------------------------------------------------------------
1 |
当前处于沙箱环境
2 | 点击“提交”可将变更合并到非沙箱环境,点击“重置”可将沙箱恢复到初始状态
3 | 点击“退出沙箱”可退出沙箱环境
4 | 以上操作都将重启设备
5 | 关机以后移除相关U盘或者移动硬盘能临时退出沙箱环境
6 | 若开发中的软件已经打包进固件并已经刷机,可“重置”沙箱以使用固件中的版本
7 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/uci-defaults/21_cpufreq:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@cpufreq[-1]
5 | add ucitrack cpufreq
6 | set ucitrack.@cpufreq[-1].init=cpufreq
7 | commit ucitrack
8 | EOF
9 |
10 | exit 0
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/uci-defaults/21_tuning_net:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@tuning_net[-1]
5 | add ucitrack tuning_net
6 | set ucitrack.@tuning_net[-1].init=tuning_net
7 | commit ucitrack
8 | EOF
9 |
10 | exit 0
--------------------------------------------------------------------------------
/luci-alias.mk:
--------------------------------------------------------------------------------
1 |
2 | LUCI_LANG.zh-cn=简体中文 (Chinese Simplified)
3 | LUCI_LANG.zh-tw=繁體中文 (Chinese Traditional)
4 | LUCI_LANG.pt-br=Português do Brasil (Brazilian Portuguese)
5 | LUCI_LANG.no=Norsk (Norwegian)
6 | LUCI_LANG.bn=বাংলা (Bengali)
7 |
8 | include $(TOPDIR)/feeds/luci/luci.mk
9 |
--------------------------------------------------------------------------------
/luci-app-fan/root/etc/uci-defaults/luci-fan:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | /usr/libexec/fan-control init
4 |
5 | uci -q batch <<-EOF >/dev/null
6 | delete ucitrack.@luci-fan[-1]
7 | add ucitrack luci-fan
8 | set ucitrack.@luci-fan[-1].init=luci-fan
9 | commit ucitrack
10 | EOF
11 |
12 | exit 0
13 |
--------------------------------------------------------------------------------
/luci-lib-mac-vendor/src/Makefile:
--------------------------------------------------------------------------------
1 | clean:
2 | compile:
3 | install:
4 | mkdir -p "$(DESTDIR)/www/luci-static/resources/mac_vendor"
5 | cp -a "$(LIB_DIST)/." "$(DESTDIR)/www/luci-static/resources/mac_vendor/"
6 | $(SED) 's#=PKG_VERSION"#=$(LIB_VERSION)"#g' "$(DESTDIR)/www/luci-static/resources/mac_vendor/mac_vendor.js"
7 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/root/usr/share/luci/menu.d/luci-app-mergerfs.json:
--------------------------------------------------------------------------------
1 | {
2 | "admin/nas/mergerfs": {
3 | "title": "MergerFS",
4 | "action": {
5 | "type": "view",
6 | "path": "mergerfs"
7 | },
8 | "depends": {
9 | "acl": [ "luci-app-mergerfs" ],
10 | "uci": { "mergerfs": true }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/mergerfs/files/mergerfs.config:
--------------------------------------------------------------------------------
1 | config pool
2 | option enabled '0'
3 | option mountpoint '/mnt/merged/movies'
4 | option paths '
5 | /mnt/nvme1/movies
6 | /mnt/nvme2/movies
7 | /mnt/nvme3/movies
8 | '
9 | option createpolicy 'epmfs'
10 | option minfreespace '100M'
11 | # option options 'defaults,cache.files=off'
12 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/sb_guide.zh-cn.htm:
--------------------------------------------------------------------------------
1 | 当前不处于沙箱环境。沙箱配置方法:
2 |
3 | - 1. 准备一个U盘或者移动硬盘,方便装卸
4 | - 2. 分区格式化成ext4
5 | - 3. 在挂载点页面配置此分区,其中 “挂载点” 选项选择 “作为外部 overlay 使用”
6 | - 4. 重启即可进入沙箱环境
7 |
8 | 注意:此沙箱实际是多层OverlayFS,方便用来实验系统配置和程序,方便开发未完成的软件,但不保护Docker和硬盘的数据
9 |
--------------------------------------------------------------------------------
/luci-app-tasks/luasrc/controller/tasks-app.lua:
--------------------------------------------------------------------------------
1 |
2 | module("luci.controller.tasks-app", package.seeall)
3 |
4 |
5 | function index()
6 | entry({"admin", "system", "tasks"}, alias("admin", "system", "tasks", "all"), _("Tasks"), 56)
7 | --entry({"admin", "system", "tasks", "user"}, cbi("tasks/user"), _("User Tasks"), 1)
8 | entry({"admin", "system", "tasks", "all"}, form("tasks/all"))
9 | end
10 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/sb_guide.htm:
--------------------------------------------------------------------------------
1 | Sandbox not working. How to start:
2 |
3 | - 1. Prepare an U disk
4 | - 2. Format to ext4
5 | - 3. Goto "Mount Points" page, setup this disk, select "Use as external overlay" in "Mount point" menu
6 | - 4. Reboot
7 |
8 | Note: this sandbox only protect overlay partition, no Docker or other disks included
9 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/sb_info.htm:
--------------------------------------------------------------------------------
1 | Sandbox is working
2 | Click "Commit" to merge changes to normal env, click "Reset" to reinitialize the sandbox
3 | Click "Exit Sandbox" to exit sandbox env
4 | Above actions will reboot device
5 | Poweroff and detach the U disk to temporarily exit sandbox env
6 | After developing app flashed, "Reset" sandbox so we can check the releaseed version
7 |
--------------------------------------------------------------------------------
/luci-app-homebox/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2016 Openwrt.org
2 | #
3 | # This is free software, licensed under the Apache License, Version 2.0 .
4 | #
5 |
6 | include $(TOPDIR)/rules.mk
7 |
8 | LUCI_TITLE:=LuCI support for homebox
9 | LUCI_DEPENDS:=+homebox
10 | LUCI_PKGARCH:=all
11 | PKG_VERSION:=1.0.1-r4
12 | PKG_RELEASE:=
13 |
14 | include ../luci-alias.mk
15 |
16 | # call BuildPackage - OpenWrt buildroot signature
17 |
18 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/Makefile:
--------------------------------------------------------------------------------
1 | # This is free software, licensed under the Apache License, Version 2.0 .
2 |
3 | include $(TOPDIR)/rules.mk
4 |
5 | LUCI_TITLE:=MergerFS
6 | LUCI_DEPENDS:=+luci-base +mergerfs
7 |
8 | LUCI_PKGARCH:=all
9 |
10 | PKG_VERSION:=1.0.3-r1
11 | PKG_RELEASE:=
12 | PKG_MAINTAINER:=jjm2473
13 |
14 | include ../luci-alias.mk
15 |
16 | # call BuildPackage - OpenWrt buildroot signature
17 |
--------------------------------------------------------------------------------
/luci-app-tasks/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (C) 2022 jjm2473
3 | #
4 | # This is free software, licensed under the MIT License.
5 | #
6 |
7 | include $(TOPDIR)/rules.mk
8 |
9 | LUCI_TITLE:=luci for taskd
10 | LUCI_DEPENDS:=+luci-lib-taskd
11 |
12 | PKG_VERSION:=1.0.0
13 | PKG_RELEASE:=
14 | PKG_MAINTAINER:=jjm2473
15 |
16 | include ../luci-alias.mk
17 |
18 | # call BuildPackage - OpenWrt buildroot signature
19 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/Makefile:
--------------------------------------------------------------------------------
1 |
2 | include $(TOPDIR)/rules.mk
3 |
4 | LUCI_TITLE:=LuCI for misc configure
5 | LUCI_PKGARCH:=all
6 | LUCI_DEPENDS:=+ethtool
7 | PKG_VERSION:=1.8.6-r3
8 | PKG_RELEASE:=
9 |
10 | define Package/luci-app-cpufreq/conffiles
11 | /etc/config/cpufreq
12 | /etc/config/tuning
13 | /etc/config/tuning_boot
14 | /etc/config/tuning_net
15 | endef
16 |
17 | include ../luci-alias.mk
18 |
19 | # call BuildPackage - OpenWrt buildroot signature
20 |
--------------------------------------------------------------------------------
/luci-app-homebox/luasrc/model/cbi/homebox.lua:
--------------------------------------------------------------------------------
1 |
2 | local m, s
3 |
4 | m = Map("homebox", translate("Homebox"), translate("Homebox is a tool for local network speed testing"))
5 |
6 | m:section(SimpleSection).template = "homebox_status"
7 |
8 | s=m:section(TypedSection, "homebox", translate("Global Settings"))
9 | s.addremove=false
10 | s.anonymous=true
11 |
12 | s:option(Flag, "enabled", translate("Enable")).rmempty=false
13 |
14 | return m
15 |
16 |
17 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/root/usr/share/rpcd/acl.d/luci-app-mergerfs.json:
--------------------------------------------------------------------------------
1 | {
2 | "luci-app-mergerfs": {
3 | "description": "Grant access to LuCI app mergerfs",
4 | "read": {
5 | "ubus": {
6 | "luci": [ "getMountPoints" ]
7 | },
8 | "uci": [ "mergerfs" ]
9 | },
10 | "write": {
11 | "file": {
12 | "/bin/umount": [ "exec" ],
13 | "/etc/init.d/mergerfs reload": [ "exec" ]
14 | },
15 | "uci": [ "mergerfs" ]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/cpuinfo.htm:
--------------------------------------------------------------------------------
1 |
13 |
14 |
--------------------------------------------------------------------------------
/luci-app-tasks/po/zh-cn/tasks.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | msgid "Tasks"
5 | msgstr "后台任务"
6 |
7 | msgid "All Tasks"
8 | msgstr "所有任务"
9 |
10 | msgid "All submitted tasks, including system defined tasks"
11 | msgstr "所有已提交的任务,包括系统定义的任务"
12 |
13 | msgid "Status"
14 | msgstr "状态"
15 |
16 | msgid "Running"
17 | msgstr "运行中"
18 |
19 | msgid "Stopped:"
20 | msgstr "已停止:"
21 |
22 | msgid "Start Time"
23 | msgstr "开始时间"
24 |
25 | msgid "Log"
26 | msgstr "日志"
27 |
28 | msgid "Remove"
29 | msgstr "移除"
30 |
--------------------------------------------------------------------------------
/luci-app-fan/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2016 Openwrt.org
2 | #
3 | # This is free software, licensed under the Apache License, Version 2.0 .
4 | #
5 |
6 | include $(TOPDIR)/rules.mk
7 |
8 | LUCI_TITLE:=LuCI fan control
9 | LUCI_DEPENDS:=+coreutils-stat
10 | LUCI_PKGARCH:=all
11 | PKG_VERSION:=1.0.0-r3
12 | PKG_RELEASE:=
13 | PKG_MAINTAINER:=jjm2473
14 |
15 | define Package/luci-app-fan/conffiles
16 | /etc/config/luci-fan
17 | endef
18 |
19 | include ../luci-alias.mk
20 |
21 | # call BuildPackage - OpenWrt buildroot signature
22 |
23 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/samba.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2021 jjm2473
4 | ]]--
5 |
6 | local m, s, o
7 |
8 | m = Map("samba4", nil, translate("Samba"))
9 |
10 | s = m:section(TypedSection, "samba", translate("Samba expert"))
11 | s.addremove=false
12 | s.anonymous=true
13 |
14 | o = s:option(Flag, "allow_legacy_protocols", translate("Allow legacy protocols"), translate("Allow old client, don't use this option for secure environments!"))
15 |
16 | -- uci set samba.@samba[0].allow_legacy_protocols=1
17 |
18 | return m
19 |
--------------------------------------------------------------------------------
/luci-app-homebox/po/zh-cn/homebox.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | msgid "Homebox"
5 | msgstr "Homebox"
6 |
7 | msgid "Click to open Homebox"
8 | msgstr "点击打开Homebox"
9 |
10 | msgid "Homebox is a tool for local network speed testing"
11 | msgstr "Homebox是一个局域网测速工具"
12 |
13 | msgid "The Homebox service is running."
14 | msgstr "Homebox服务已启动"
15 |
16 | msgid "The Homebox service is not running."
17 | msgstr "Homebox服务未启动"
18 |
19 | msgid "Homebox Status"
20 | msgstr "Homebox服务状态"
21 |
22 | msgid "Collecting data..."
23 | msgstr "收集数据..."
24 |
25 |
--------------------------------------------------------------------------------
/homebox/files/homebox.init:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=99
4 | USE_PROCD=1
5 |
6 | get_config() {
7 | config_get_bool enabled $1 enabled 1
8 | config_get_bool logger $1 logger
9 | }
10 |
11 | start_service() {
12 | config_load homebox
13 | config_foreach get_config homebox
14 | [ $enabled != 1 ] && return 1
15 |
16 | procd_open_instance
17 | procd_set_param command /usr/bin/homebox
18 | [ "$logger" == 1 ] && procd_set_param stderr 1
19 | procd_set_param respawn
20 | procd_close_instance
21 | }
22 |
23 | service_triggers() {
24 | procd_add_reload_trigger "homebox"
25 | }
26 |
--------------------------------------------------------------------------------
/mergerfs/files/mergerfs.fstab:
--------------------------------------------------------------------------------
1 | if /etc/init.d/mergerfs enabled && [ -f /etc/config/mergerfs ]; then
2 | (
3 | . /lib/functions.sh
4 |
5 | add_paths() {
6 | local section="$1"
7 | local enabled paths
8 |
9 | config_get_bool enabled "$section" enabled 0
10 | [ "$enabled" -eq 1 ] || return 0
11 |
12 | config_get paths "$section" paths
13 |
14 | # (
15 | printf "%s\n" "$paths" | while IFS= read -r p; do
16 | case "$p" in
17 | /*) fstab_add_essential_mountpoint "$p"
18 | ;;
19 | esac
20 | done
21 | }
22 | config_load mergerfs
23 | config_foreach add_paths pool
24 | )
25 | fi
26 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/init.d/tuning:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=20
4 |
5 | ipk_config() {
6 | config_get ipk_mirror $1 mirror "disable"
7 | }
8 |
9 | start() {
10 | config_load tuning
11 | config_foreach ipk_config ipk
12 |
13 | if [ "$ipk_mirror" != "disable" -a -f "/rom/etc/opkg/distfeeds.conf" ]; then
14 | echo "# Generated file, do not edit" > /etc/opkg/distfeeds.conf
15 | cat "/rom/etc/opkg/distfeeds.conf" | \
16 | sed -E 's# https?://[^ ]+/openwrt/# https://downloads.openwrt.org/#g' | \
17 | sed -E 's#https?://downloads.openwrt.org/#'"$ipk_mirror"'#g' >> /etc/opkg/distfeeds.conf
18 | fi
19 |
20 | return 0
21 | }
22 |
--------------------------------------------------------------------------------
/luci-app-fan/root/etc/init.d/luci-fan:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=20
4 |
5 | boot() {
6 | /usr/libexec/fan-control init
7 | start
8 | }
9 |
10 | start_instance() {
11 | local enabled
12 | config_get_bool enabled $1 enabled 0
13 | [[ "$enabled" = 1 ]] || return 0
14 |
15 | config_get on_temp $1 on_temp
16 | config_get off_temp $1 off_temp
17 |
18 | [[ -n "$on_temp" ]] && on_temp=${on_temp}000
19 | [[ -n "$off_temp" ]] && off_temp=${off_temp}000
20 |
21 | /usr/libexec/fan-control set "$on_temp" $off_temp
22 | }
23 |
24 | start() {
25 | config_load luci-fan
26 | config_foreach start_instance luci-fan
27 | return 0
28 | }
29 |
--------------------------------------------------------------------------------
/mergerfs/patches/002-fix-install.patch:
--------------------------------------------------------------------------------
1 | diff --git a/libfuse/Makefile b/libfuse/Makefile
2 | index a20b0742..53959713 100644
3 | --- a/libfuse/Makefile
4 | +++ b/libfuse/Makefile
5 | @@ -136,8 +136,8 @@ strip:
6 | install-utils: mergerfs-fusermount mount.mergerfs strip
7 | install -D build/mergerfs-fusermount "$(INSTALLBINDIR)/mergerfs-fusermount"
8 | install -D build/mount.mergerfs "$(INSTALLSBINDIR)/mount.mergerfs"
9 | - chown root "$(INSTALLBINDIR)/mergerfs-fusermount"
10 | - chmod u+s "$(INSTALLBINDIR)/mergerfs-fusermount"
11 | +# chown root "$(INSTALLBINDIR)/mergerfs-fusermount"
12 | +# chmod u+s "$(INSTALLBINDIR)/mergerfs-fusermount"
13 |
14 | install: $(INSTALLUTILS)
15 |
16 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/init.d/cpufreq:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=20
4 |
5 | get_config() {
6 | config_get governor $1 governor
7 | config_get speed $1 speed
8 | }
9 |
10 | start() {
11 | config_load cpufreq
12 | config_foreach get_config cpufreq
13 |
14 | [[ -n "$governor" ]] || return 1
15 |
16 | local policy
17 | for policy in `ls /sys/devices/system/cpu/cpufreq/ | grep '^policy'`; do
18 | sh -c "echo '$governor' > /sys/devices/system/cpu/cpufreq/$policy/scaling_governor" 2>/dev/null
19 | [[ "$governor" = "userspace" && -n "$speed" ]] && sh -c "echo '$speed' > /sys/devices/system/cpu/cpufreq/$policy/scaling_setspeed" 2>/dev/null
20 | done
21 |
22 | return 0
23 | }
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/net.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2022 jjm2473
4 | ]]--
5 |
6 | local m, s, o
7 |
8 | m = Map("tuning_net", nil, translate("Network"))
9 |
10 | s = m:section(TypedSection, "hw_acct", translate("Hardware Acceleration"))
11 | s.addremove=false
12 | s.anonymous=true
13 |
14 | o = s:option(Flag, "wan_acct", translate("Enable WAN Port Acceleration"), translate("Improve built-in WAN port (eth0) TX performace"))
15 | o.default="1"
16 |
17 | o = s:option(Flag, "hw_pppoe", translate("Enable PPPoE Acceleration"), translate("Improve PPPoE TX performace, only support built-in NICs"))
18 | o.rmempty=true
19 | o:depends('wan_acct', 1)
20 |
21 | return m
22 |
--------------------------------------------------------------------------------
/luci-app-homebox/luasrc/controller/homebox.lua:
--------------------------------------------------------------------------------
1 | module("luci.controller.homebox", package.seeall)
2 |
3 | function index()
4 | if not nixio.fs.access("/etc/config/homebox") then
5 | return
6 | end
7 |
8 | entry({"admin", "services", "homebox"}, cbi("homebox"), _("Homebox"), 20).dependent = true
9 |
10 | entry({"admin", "services", "homebox_status"}, call("homebox_status"))
11 | end
12 |
13 | function homebox_status()
14 | local sys = require "luci.sys"
15 | local uci = require "luci.model.uci".cursor()
16 |
17 | local status = {
18 | running = (sys.call("pidof homebox >/dev/null 2>&1") == 0),
19 | port = 3300
20 | }
21 |
22 | luci.http.prepare_content("application/json")
23 | luci.http.write_json(status)
24 | end
25 |
--------------------------------------------------------------------------------
/mergerfs/patches/003-fix-build-non-x86-target.patch:
--------------------------------------------------------------------------------
1 | From eebe9562d62e990dd80e7b5550492a2b4175cb44 Mon Sep 17 00:00:00 2001
2 | From: jjm2473
3 | Date: Thu, 7 Aug 2025 21:35:54 +0800
4 | Subject: [PATCH] fix build on openwrt arm64 target
5 |
6 | let openwrt handles stripping
7 | ---
8 | libfuse/Makefile | 4 ++--
9 | 1 file changed, 2 insertions(+), 2 deletions(-)
10 |
11 | diff --git a/libfuse/Makefile b/libfuse/Makefile
12 | index 53959713..04e03396 100644
13 | --- a/libfuse/Makefile
14 | +++ b/libfuse/Makefile
15 | @@ -130,8 +130,8 @@ clean:
16 | distclean: clean
17 |
18 | strip:
19 | - strip --strip-all build/mount.mergerfs
20 | - strip --strip-all build/mergerfs-fusermount
21 | +# strip --strip-all build/mount.mergerfs
22 | +# strip --strip-all build/mergerfs-fusermount
23 |
24 | install-utils: mergerfs-fusermount mount.mergerfs strip
25 | install -D build/mergerfs-fusermount "$(INSTALLBINDIR)/mergerfs-fusermount"
26 | --
27 | 2.46.0
28 |
29 |
--------------------------------------------------------------------------------
/luci-app-homebox/luasrc/view/homebox_status.htm:
--------------------------------------------------------------------------------
1 |
21 |
22 |
28 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/init.d/tuning_net:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=19
4 |
5 | hwacct_config() {
6 | config_get wanacct_enabled $1 wan_acct "1"
7 | config_get hwpppoe_enabled $1 hw_pppoe "0"
8 | }
9 |
10 | boot() {
11 | local feature=`ethtool -k eth0 2>/dev/null | grep -F hw-pppoe: 2>/dev/null`
12 | [[ -n "$feature" ]] || return 1
13 |
14 | echo "$feature" | grep -qF '[fixed]' && return 1
15 |
16 | local hwpppoe_enabled
17 | local wanacct_enabled
18 | local hwpppoe=off
19 | local wanacct=on
20 | config_load tuning_net
21 | config_foreach hwacct_config hw_acct
22 | [ "$wanacct_enabled" = 0 ] && wanacct=off
23 | [ "$wanacct_enabled" = 1 -a "$hwpppoe_enabled" = 1 ] && hwpppoe=on
24 |
25 | ethtool -K eth0 hw-pppoe $hwpppoe tx-checksum-ip-generic $wanacct tx-scatter-gather $wanacct generic-receive-offload $wanacct 2>/dev/null
26 | ethtool -K eth1 hw-pppoe $hwpppoe 2>/dev/null
27 |
28 | return 0
29 | }
30 |
31 | start() {
32 | boot && /etc/init.d/network restart
33 | }
34 |
--------------------------------------------------------------------------------
/luci-app-tasks/luasrc/view/tasks/all.htm:
--------------------------------------------------------------------------------
1 | <%+tasks/embed%>
2 |
3 |
29 |
--------------------------------------------------------------------------------
/luci-lib-mac-vendor/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2016 Openwrt.org
2 | #
3 | # This is free software, licensed under the Apache License, Version 2.0 .
4 | #
5 |
6 | include $(TOPDIR)/rules.mk
7 |
8 | LUCI_TITLE:=LuCI mac to vendor map
9 | LUCI_DESCRIPTION:=provide a js for mac address to vendor mapping
10 | LUCI_PKGARCH:=all
11 |
12 | PKG_VERSION:=1.0.0-r2
13 | # PKG_RELEASE MUST be empty for luci.mk
14 | PKG_RELEASE:=
15 |
16 | LIB_VERSION:=1.0.2
17 | PKG_HASH:=519ddb8a7a4d3b0e9b2fa5f01ffc7a20ef3af80201d6630c3fffc05e7374e0af
18 |
19 | PKG_SOURCE_URL_FILE:=v$(LIB_VERSION).tar.gz
20 | PKG_SOURCE:=mac_vendor-$(PKG_SOURCE_URL_FILE)
21 | PKG_SOURCE_URL:=https://github.com/jjm2473/mac_vendor/archive/refs/tags
22 |
23 | PKG_MAINTAINER:=jjm2473
24 |
25 | TARGET_CONFIGURE_OPTS= LIB_DIST="$(BUILD_DIR)/mac_vendor-$(LIB_VERSION)/dist" LIB_VERSION="$(LIB_VERSION)"
26 | TARGET_CONFIGURE_OPTS+= SED="$(SED)"
27 |
28 | include $(TOPDIR)/feeds/luci/luci.mk
29 |
30 | # call BuildPackage - OpenWrt buildroot signature
31 |
32 |
--------------------------------------------------------------------------------
/ssd1306/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | I2C=$1
4 | [ -z "$I2C" ] && exit 1
5 |
6 | ROTATE=180
7 | # clear display every round for broken displays
8 | CLEAR=false
9 |
10 | LINELEN=21 # 128/6
11 | MAX=42 # 2 lines
12 | TEXT="Hello world!"
13 |
14 |
15 | len=`echo "$TEXT" | wc -c`
16 | if [ $len -gt $MAX ]; then
17 | echo "Text too long (max $MAX chars)" >&2
18 | exit 1
19 | fi
20 | fillround=$(( ($MAX + $len) / $len )).
21 | offset=0
22 |
23 | ssd1306 -n $I2C -I 128x32
24 | # rotate display
25 | ssd1306 -n $I2C -r $ROTATE
26 | if $CLEAR; then
27 | sleep 1
28 | else
29 | ssd1306 -n $I2C -c
30 | fi
31 | while :; do
32 | halfstart=$(($offset + $LINELEN))
33 | text=""
34 | for i in $(seq 0 $fillround); do
35 | text="$text ${TEXT}"
36 | done
37 | $CLEAR && ssd1306 -n $I2C -c
38 | msg="`date '+%Y-%m-%d %H:%M:%S'`"' \n'"${text:$offset:$LINELEN}"'\n'"${text:$halfstart:$LINELEN}"'\n'"`date '+%Y-%m-%d %H:%M:%S'` "
39 | ssd1306 -n $I2C -m "$msg"
40 | sleep 1
41 | offset=$(( ($offset + 1) % $len ))
42 | done
43 | exit 0
44 |
--------------------------------------------------------------------------------
/mergerfs/patches/001-fix-lto.patch:
--------------------------------------------------------------------------------
1 | diff --git a/libfuse/lib/fmt/format.h b/libfuse/lib/fmt/format.h
2 | index 7c607dbd..c08d6ca5 100644
3 | --- a/libfuse/lib/fmt/format.h
4 | +++ b/libfuse/lib/fmt/format.h
5 | @@ -1604,10 +1604,10 @@ auto snprintf_float(T value, int precision, float_specs specs,
6 | abort_fuzzing_if(precision > 100000);
7 | // Suppress the warning about a nonliteral format string.
8 | // Cannot use auto because of a bug in MinGW (#1532).
9 | - int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
10 | + //int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
11 | int result = precision >= 0
12 | - ? snprintf_ptr(begin, capacity, format, precision, value)
13 | - : snprintf_ptr(begin, capacity, format, value);
14 | + ? snprintf(begin, capacity, format, precision, value)
15 | + : snprintf(begin, capacity, format, value);
16 | if (result < 0) {
17 | // The buffer will grow exponentially.
18 | buf.try_reserve(buf.capacity() + 1);
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 练亮斌
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/root/etc/init.d/await_fstab:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=11
4 |
5 | boot() {
6 | local enabled=`uci get tuning_boot.@fstab_delay[0].enabled 2>/dev/null`
7 | [ -z "$enabled" -o "$enabled" = 0 ] && return 0
8 |
9 | local timeout=`uci get tuning_boot.@fstab_delay[0].timeout 2>/dev/null`
10 | [ -z "$timeout" -o "$timeout" = 0 ] && return 0
11 |
12 | local devices=`uci get tuning_boot.@fstab_delay[0].device 2>/dev/null`
13 |
14 | if [ -n "$devices" ]; then
15 | echo "fstab_delay: wait up to $timeout seconds for device(s): $devices" >/dev/kmsg
16 | local i=0
17 | local dev
18 | local ready
19 | while [ $i -lt $timeout ]; do
20 | ready=1
21 | for dev in $devices ; do
22 | blkid --uuid $dev >/dev/null 2>&1 || { ready=0; break; }
23 | done
24 | [ $ready -eq 1 ] && break
25 | sleep 1
26 | i=$(($i+1))
27 | done
28 | if [ $i -lt $timeout ]; then
29 | echo "fstab_delay: ready after $i seconds" >/dev/kmsg
30 | else
31 | echo "fstab_delay: wait device(s) timeout" >/dev/kmsg
32 | fi
33 | else
34 | echo "fstab_delay: sleep $timeout seconds before fstab" >/dev/kmsg
35 | sleep $timeout
36 | fi
37 | return 0
38 | }
39 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/kmods.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2023 jjm2473
4 | ]]--
5 |
6 | local files = io.popen("ls /etc/modules-pending.d/", "r")
7 | local ln, drivers = nil, {}
8 |
9 | while ( true )
10 | do
11 | ln = files:read("*l")
12 | if not ln or ln == "" then
13 | break
14 | end
15 | drivers[#drivers+1] = luci.util.trim(ln)
16 | end
17 |
18 | files:close()
19 |
20 | local m, s, o, i, d
21 |
22 | m = Map("kmods", nil, translate("Configure device drivers, kernel modules, etc. Changes here will take effect on next boot"))
23 |
24 | s = m:section(NamedSection, "kmods", "global", translate("Drivers Settings"))
25 | s.addremove=false
26 | s.anonymous=true
27 |
28 | local known = {
29 | ['r8125'] = translate("Realtek r8125 driver"),
30 | ['r8168'] = translate("Realtek r8168 driver"),
31 | ['i915-oot'] = translate("Backported Intel GPU driver (i915-oot)"),
32 | }
33 |
34 | o = s:option(StaticList, "enable", translate("Enable additional drivers"), translate("Please do not choose a driver you do not understand. Choosing the wrong driver may cause the system to fail to start"))
35 | for i, d in ipairs(drivers) do
36 | o:value(d, known[d] or d )
37 | end
38 |
39 | return m
40 |
--------------------------------------------------------------------------------
/ssd1306/Makefile:
--------------------------------------------------------------------------------
1 |
2 | include $(TOPDIR)/rules.mk
3 |
4 | PKG_NAME:=ssd1306
5 | PKG_RELEASE:=1
6 |
7 | PKG_SOURCE_DATE:=2024-10-11
8 | PKG_SOURCE_VERSION:=19128ed4b6108408fea05b9d0551236b6d638dbc
9 | PKG_SOURCE:=ssd1306_linux-$(PKG_SOURCE_DATE).tar.gz
10 | PKG_SOURCE_URL:=https://codeload.github.com/armlabs/ssd1306_linux/tar.gz/$(PKG_SOURCE_VERSION)?
11 | PKG_HASH:=1cab77ce23e32c2740ab66ba40dda51b34ebbc28fabb477aad50102b3916b8c2
12 |
13 | PKG_MAINTAINER:=jjm2473
14 | PKG_LICENSE:=MIT
15 | PKG_LICENSE_FILES:=LICENSE
16 |
17 | include $(INCLUDE_DIR)/package.mk
18 |
19 | define Package/ssd1306
20 | SECTION:=utils
21 | CATEGORY:=Utilities
22 | TITLE:=SSD1306 OLED I2C Driver
23 | URL:=https://github.com/armlabs/ssd1306_linux
24 | endef
25 |
26 | define Package/ssd1306/description
27 | SSD1306 oled I2C driver working in linux
28 | endef
29 |
30 | TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS)
31 | TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
32 |
33 | define Package/ssd1306/install
34 | $(INSTALL_DIR) $(1)/usr/bin
35 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/ssd1306 $(1)/usr/bin
36 | endef
37 |
38 | # Set variables used in the source's Makefile
39 | MAKE_FLAGS+= BIN="ssd1306" LDFLAGS=""
40 |
41 | $(eval $(call BuildPackage,ssd1306))
42 |
--------------------------------------------------------------------------------
/luci-app-fan/luasrc/view/luci-fan.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
<%:Status%>
4 |
5 |
6 | | <%:Thermal zone%> | <%=self.thermal_zone%> (<%:type:%> <%=self.thermal_type%>) |
7 | | <%:Trip point%> | trip_point_<%=self.trip_point%> |
8 | | <%:Fan start temperature%> | |
9 | | <%:Current temperature%> | |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/luci-app-fan/luasrc/controller/admin/luci-fan.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2023 jjm2473
4 | ]]--
5 |
6 | module("luci.controller.admin.luci-fan", package.seeall)
7 |
8 | function index()
9 | require "luci.sys"
10 | local appname = "luci-fan"
11 | local defaultpage = nil
12 | if luci.sys.call("/usr/libexec/fan-control get >/dev/null 2>&1") == 0 then
13 | entry({"admin", "system", appname}, cbi("luci-fan"), _("Fan Control"), 60)
14 | else
15 | entry({"admin", "system", appname}).dependent = true
16 | end
17 | entry({"admin", "system", appname, "get_fan_info"}, call("get_fan_info"), nil).leaf = true
18 | end
19 |
20 | function get_fan_info(zone, trip)
21 | require "luci.util"
22 | local words
23 | if zone and trip and string.match(zone, "^thermal_zone%d+$") and string.match(trip, "^%d+$") then
24 | local fs = require "nixio.fs"
25 | words = {
26 | luci.util.trim(fs.readfile("/sys/class/thermal/"..zone.."/temp")),
27 | luci.util.trim(fs.readfile("/sys/class/thermal/"..zone.."/trip_point_"..trip.."_temp"))
28 | }
29 | else
30 | local sys = require "luci.sys"
31 | words = luci.util.split(luci.util.trim(sys.exec("/usr/libexec/fan-control temp 2>/dev/null")), " ")
32 | end
33 | local zone_temp = tonumber(words[1]) / 1000; -- ˚C
34 | local fan_on_temp = tonumber(words[2]) / 1000; -- ˚C
35 | luci.http.status(200, "ok")
36 | luci.http.prepare_content("application/json")
37 | luci.http.write_json({zone_temp=zone_temp, fan_on_temp=fan_on_temp})
38 | end
39 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/ipk.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2021 jjm2473
4 | ]]--
5 |
6 | local m, s, o
7 |
8 | m = Map("tuning", nil, translate("Select IPK Mirror server"))
9 |
10 | s = m:section(TypedSection, "ipk")
11 | s.addremove=false
12 | s.anonymous=true
13 |
14 | o = s:option(ListValue, "mirror", translate("Mirror server"))
15 | o:value("disable", "")
16 | o:value("http://downloads.openwrt.org/", translate("OpenWRT") .. " (HTTP)")
17 | o:value("https://downloads.openwrt.org/", translate("OpenWRT") .. " (HTTPS)")
18 | o:value("https://mirrors.cernet.edu.cn/openwrt/", translate("CERNET 302"))
19 | o:value("https://mirrors.sustech.edu.cn/openwrt/", translate("SUSTech"))
20 | o:value("https://mirrors.tuna.tsinghua.edu.cn/openwrt/", translate("Tsinghua University"))
21 | o:value("https://mirrors.ustc.edu.cn/openwrt/", translate("USTC"))
22 | o:value("https://mirror.lzu.edu.cn/openwrt/", translate("Lanzhou University"))
23 | o:value("https://mirrors.aliyun.com/openwrt/", translate("Alibaba Cloud"))
24 | o:value("https://mirrors.cloud.tencent.com/openwrt/", translate("Tencent Cloud"))
25 | o:value("https://mirror.iscas.ac.cn/openwrt/", translate("Chinese Academy of Sciences"))
26 | o:value("https://mirror.nyist.edu.cn/openwrt/", translate("NYIST"))
27 | o:value("https://mirror.sjtu.edu.cn/openwrt/", translate("SJTU"))
28 | o:value("https://mirrors.cqupt.edu.cn/openwrt/", translate("CQUPT"))
29 | o:value("https://mirrors.qlu.edu.cn/openwrt/", translate("Qilu University of Technology"))
30 |
31 | o.rmempty = false
32 | o.default = "disable"
33 |
34 | return m
35 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/main.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2021 jjm2473
4 | ]]--
5 |
6 | local m, s, o
7 | require "luci.util"
8 |
9 | local governor_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
10 |
11 | local fs = require "nixio.fs"
12 |
13 | m = Map("cpufreq", nil, translate("Manage CPU performance over LuCI."))
14 | m:section(SimpleSection).template = "cpufreq/cpuinfo"
15 |
16 | s = m:section(TypedSection, "cpufreq")
17 | s.addremove=false
18 | s.anonymous=true
19 |
20 | local cur_governor = luci.util.trim(fs.readfile(governor_path))
21 |
22 | o = s:option(ListValue, "governor", translate("CPUFreq governor"), translate("It is recommended to use 'ondemand' or 'schedutil'"))
23 | o:value("", translate("Default (Take effect after reboot)"))
24 | for i,v in pairs(luci.util.split(luci.util.trim(fs.readfile("/sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors")), " ")) do
25 | o:value(v, translate(v))
26 | end
27 | o.default = cur_governor
28 |
29 | local available_frequencies = luci.util.split(luci.util.trim(fs.readfile("/sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies")), " ")
30 |
31 | if #available_frequencies > 0 then
32 | o = s:option(ListValue, "speed", translate("Frequency"), translate("Pay attention to heat dissipation when choosing high frequency"))
33 | o:depends("governor", "userspace")
34 | for i,v in pairs(available_frequencies) do
35 | o:value(v, (tonumber(v)/1000) .. " MHz")
36 | end
37 | o.rmempty = true
38 | o.default = available_frequencies[1]
39 | end
40 |
41 | return m
42 |
--------------------------------------------------------------------------------
/nvtop/Makefile:
--------------------------------------------------------------------------------
1 |
2 | include $(TOPDIR)/rules.mk
3 |
4 | PKG_NAME:=nvtop
5 | PKG_VERSION:=3.2.0
6 | PKG_RELEASE:=2
7 |
8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
9 | PKG_SOURCE_URL:=https://codeload.github.com/Syllo/$(PKG_NAME)/tar.gz/$(PKG_VERSION)?
10 | PKG_HASH:=d26df685455023cedc4dda033862dcddb67402fbdb685da70da78492f73c41d0
11 |
12 | PKG_MAINTAINER:=jjm2473
13 | PKG_LICENSE:=GPL-3.0+
14 |
15 | PKG_CONFIG_DEPENDS:= \
16 | CONFIG_LIBDRM_AMDGPU
17 |
18 | include $(INCLUDE_DIR)/package.mk
19 | include $(INCLUDE_DIR)/cmake.mk
20 |
21 | define Package/nvtop
22 | SECTION:=utils
23 | CATEGORY:=Utilities
24 | TITLE:=NVTOP
25 | DEPENDS:=@(aarch64||x86_64) +libncursesw +libudev +libdrm
26 | URL:=https://github.com/Syllo/nvtop
27 | endef
28 |
29 | define Package/nvtop/description
30 | NVTOP stands for Neat Videocard TOP, a (h)top like task monitor for GPUs and accelerators
31 | endef
32 |
33 | TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
34 |
35 | CMAKE_OPTIONS += \
36 | -DUSE_LIBUDEV_OVER_LIBSYSTEMD=ON \
37 | -DAPPLE_SUPPORT=OFF \
38 | -DNVIDIA_SUPPORT=OFF \
39 | -DASCEND_SUPPORT=OFF \
40 | -DTPU_SUPPORT=OFF
41 |
42 | ifdef CONFIG_aarch64
43 | CMAKE_OPTIONS += \
44 | -DPANFROST_SUPPORT=ON \
45 | -DPANTHOR_SUPPORT=ON \
46 | -DAMDGPU_SUPPORT=OFF \
47 | -DINTEL_SUPPORT=OFF
48 | else
49 | CMAKE_OPTIONS += \
50 | -DPANFROST_SUPPORT=OFF \
51 | -DPANTHOR_SUPPORT=OFF \
52 | -DAMDGPU_SUPPORT=$(if $(CONFIG_LIBDRM_AMDGPU),ON,OFF) \
53 | -DINTEL_SUPPORT=ON \
54 | -DV3D_SUPPORT=OFF
55 | endif
56 |
57 | define Package/nvtop/install
58 | $(INSTALL_DIR) $(1)/usr/bin
59 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nvtop $(1)/usr/bin/
60 | endef
61 |
62 | $(eval $(call BuildPackage,nvtop))
63 |
--------------------------------------------------------------------------------
/luci-app-tasks/luasrc/model/cbi/tasks/all.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | ]]--
4 |
5 | local taskd = require "luci.model.tasks"
6 | local tasks = taskd.status()
7 | local show_log_taskid
8 | local m, s, o
9 |
10 | local t=Template("tasks/all")
11 |
12 | m = SimpleForm("taskd",
13 | translate("All Tasks"),
14 | translate("All submitted tasks, including system defined tasks"))
15 | m.submit=false
16 | m.reset=false
17 |
18 | s = m:section(Table, tasks)
19 | s.config = "tasks"
20 |
21 | o = s:option(DummyValue, "_id", translate("ID"))
22 | o.width="10%"
23 | o.cfgvalue = function(self, section)
24 | return section
25 | end
26 |
27 | o = s:option(DummyValue, "_status", translate("Status"))
28 | o.width="15%"
29 | o.cfgvalue = function(self, section)
30 | local task = tasks[section]
31 | return task.running and translate("Running") or (translate("Stopped:") .. " " .. task.exit_code)
32 | end
33 |
34 | o = s:option(DummyValue, "_start", translate("Start Time"))
35 | o.width="15%"
36 | o.cfgvalue = function(self, section)
37 | local task = tasks[section]
38 | return os.date("%Y/%m/%d %H:%M:%S", task.start)
39 | end
40 | -- os.date("%Y/%m/%d %H:%M:%S", 1657163212)
41 |
42 | local btn_log = s:option(Button, "_log", translate("Log"))
43 | btn_log.inputstyle = "find"
44 | btn_log.write = function(self, section, value)
45 | t.show_log_taskid = section
46 | end
47 |
48 | local btn_remove = s:option(Button, "_remove", translate("Remove"))
49 | btn_remove.inputstyle = "remove"
50 | btn_remove.forcewrite = true
51 | btn_remove.write = function(self, section, value)
52 | local task_id = section
53 | os.execute("/etc/init.d/tasks task_del "..task_id.." >/dev/null 2>&1")
54 | tasks[task_id] = nil
55 | end
56 |
57 | m:append(t)
58 |
59 | return m
60 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/boot.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2021 jjm2473
4 | ]]--
5 |
6 | local fs = require "nixio.fs"
7 |
8 | local block = io.popen("block info", "r")
9 | local ln, dev, devices = nil, nil, {}
10 |
11 | repeat
12 | ln = block:read("*l")
13 | dev = ln and ln:match("^/dev/(.-):")
14 |
15 | if dev then
16 | local e, s, key, val = { }
17 |
18 | for key, val in ln:gmatch([[(%w+)="(.-)"]]) do
19 | e[key:lower()] = val
20 | end
21 |
22 | s = tonumber((fs.readfile("/sys/class/block/%s/size" % dev)))
23 |
24 | e.dev = "/dev/%s" % dev
25 | e.size = s and math.floor(s / 2048)
26 |
27 | devices[#devices+1] = e
28 | end
29 | until not ln
30 |
31 | block:close()
32 |
33 |
34 | local m, s, o
35 |
36 | m = Map("tuning_boot", nil, translate("Boot"))
37 |
38 | s = m:section(TypedSection, "fstab_delay", translate("Delay before disk mounting"),
39 | translate("Wait for the hard disk to initialize to solve the problem that the hard disk is not mounted when some applications that rely on the hard disk are started.")
40 | .. "
" .. translate("Do not select a network block device (e.g. NBD, iSCSI, etc.), you may have to wait until timeout."))
41 | s.addremove=false
42 | s.anonymous=true
43 |
44 | o = s:option(Flag, "enabled", translate("Enable"))
45 |
46 | o = s:option(Value, "timeout", translate("Timeout (seconds)"))
47 | o:value("5", "5")
48 | o:value("10", "10")
49 | o:value("30", "30")
50 | o:value("60", "60")
51 | o:depends("enabled", 1)
52 | o.default = "5"
53 |
54 | o = s:option(DynamicList, "device", translate("Or until these device(s) ready (UUID):"))
55 | o:depends("enabled", 1)
56 | for i, d in ipairs(devices) do
57 | if d.uuid and d.size then
58 | o:value(d.uuid, "%s (%s, %d MB)" %{ d.uuid, d.dev, d.size })
59 | elseif d.uuid then
60 | o:value(d.uuid, "%s (%s)" %{ d.uuid, d.dev })
61 | end
62 | end
63 |
64 | return m
65 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/model/cbi/cpufreq/cmdline.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2024 jjm2473
4 | ]]--
5 |
6 | require "luci.util"
7 | require "luci.xml"
8 | local fs = require "nixio.fs"
9 |
10 | local m, s, o
11 |
12 | m = Map("grub", nil, translate("This page configures Linux kernel boot parameters. After saving and applying, the GRUB configuration file of the boot partition will be modified. The parameters will take effect after restarting the system (the boot partition is not within the scope of sandbox protection, please be aware)"))
13 | s = m:section(SimpleSection, translate("Current Cmdline"), luci.xml.pcdata(luci.util.trim(fs.readfile("/proc/cmdline") or "")))
14 |
15 | if fs.access("/etc/grub.cfg.d/01-iommu.cfg") then
16 | s = m:section(NamedSection, "iommu", "iommu", "IOMMU", translate("Supports PCI device passthrough for virtual machines (KVM/QEMU)"))
17 | s.addremove=false
18 | s.anonymous=true
19 |
20 | o = s:option(Flag, "enabled", translate("Enabled"))
21 |
22 | o = s:option(Value, "cmdline", translate("Parameters"), translate("Default or empty will be automatically filled in according to the current platform"))
23 | o:value("", translate("Default"))
24 | o:value("intel_iommu=on iommu=pt", "Intel (intel_iommu=on iommu=pt)")
25 | o:value("amd_iommu=on iommu=pt", "AMD (amd_iommu=on iommu=pt)")
26 |
27 | end
28 |
29 | s = m:section(TypedSection, "cmdline", translate("Custom Parameters"),
30 | translate("Danger! If you do not understand the kernel boot parameters, do not modify them to avoid being unable to start or damaging the hardware"))
31 | s.addremove=true
32 | s.anonymous=true
33 | s.template = "cbi/tblsection"
34 |
35 | o = s:option(Flag, "enabled", translate("Enabled"))
36 |
37 | o = s:option(Value, "cmdline", translate("Parameters"))
38 | o.datatype = "string"
39 | o.rmempty = false
40 |
41 | o = s:option(Value, "comment", translate("Comment"))
42 |
43 | return m
44 |
--------------------------------------------------------------------------------
/duperemove/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # This is free software, licensed under the GNU General Public License v2.
3 | # See /LICENSE for more information.
4 | #
5 |
6 | include $(TOPDIR)/rules.mk
7 |
8 | PKG_NAME:=duperemove
9 | PKG_VERSION:=0.15.1
10 | PKG_RELEASE:=1
11 |
12 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
13 | PKG_SOURCE_URL:=https://codeload.github.com/markfasheh/duperemove/tar.gz/v$(PKG_VERSION)?
14 | PKG_HASH:=68cc28f5aa43fa2034e512f7b22cf5282ce2b0319b4e1061f7cdf55cc134273b
15 |
16 | PKG_MAINTAINER:=Mark Fasheh
17 | PKG_LICENSE:=GPL-2.0
18 | PKG_LICENSE_FILES:=LICENSE
19 |
20 | include $(INCLUDE_DIR)/package.mk
21 |
22 | define Package/duperemove
23 | SECTION:=utils
24 | CATEGORY:=Utilities
25 | SUBMENU:=Filesystem
26 | TITLE:=Duplicate file removal tool
27 | URL:=https://github.com/markfasheh/duperemove
28 | DEPENDS:= \
29 | +libsqlite3 \
30 | +glib2 \
31 | +libxxhash \
32 | +libuuid \
33 | +libmount \
34 | +libblkid \
35 | +libbsd \
36 | +libatomic
37 | endef
38 |
39 | define Package/duperemove/description
40 | Duperemove is a simple tool for finding duplicated extents and submitting
41 | them for deduplication. When given a list of files it will hash their
42 | contents on an extent by extent basis and compare those hashes to each
43 | other, finding and categorizing extents that match each other. Optionally,
44 | a per-block hash can be applied for further duplication lookup. When given
45 | the -d option, duperemove will submit those extents for deduplication using
46 | the Linux kernel FIDEDUPRANGE ioctl.
47 | endef
48 |
49 | define Package/duperemove/install
50 | $(INSTALL_DIR) $(1)/usr/bin
51 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/duperemove $(1)/usr/bin
52 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/hashstats $(1)/usr/bin
53 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/btrfs-extent-same $(1)/usr/bin
54 | endef
55 |
56 | # Set variables used in the source's Makefile
57 | MAKE_FLAGS+= VERSION="$(PKG_VERSION)" IS_RELEASE=1
58 |
59 | $(eval $(call BuildPackage,duperemove))
60 |
--------------------------------------------------------------------------------
/mergerfs/Makefile:
--------------------------------------------------------------------------------
1 |
2 | include $(TOPDIR)/rules.mk
3 |
4 | PKG_NAME:=mergerfs
5 | PKG_VERSION:=2.40.2
6 | PKG_RELEASE:=5
7 |
8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
9 | PKG_SOURCE_URL:=https://github.com/trapexit/mergerfs/releases/download/$(PKG_VERSION)/
10 | PKG_HASH:=595a7a108f5a20e0cd20b6d08a360b283940d81b1a66b118d27dfa93540878b0
11 |
12 | PKG_MAINTAINER:=jjm2473
13 | PKG_LICENSE:=ISC
14 | PKG_LICENSE_FILES:=LICENSE
15 |
16 | PKG_INSTALL:=1
17 |
18 | include $(INCLUDE_DIR)/package.mk
19 |
20 | define Package/mergerfs
21 | SECTION:=utils
22 | CATEGORY:=Utilities
23 | SUBMENU:=Filesystem
24 | TITLE:=A featureful union filesystem
25 | URL:=https://github.com/trapexit/mergerfs
26 | DEPENDS:=+libstdcpp
27 | endef
28 |
29 | define Package/mergerfs/description
30 | mergerfs is a FUSE based union filesystem geared towards simplifying
31 | storage and management of files across numerous commodity storage
32 | devices. It is similar to mhddfs, unionfs, and aufs.
33 | endef
34 |
35 | define Package/mergerfs/conffiles
36 | /etc/config/mergerfs
37 | endef
38 |
39 | define Package/mergerfs/install
40 | $(INSTALL_DIR) $(1)/sbin/fs $(1)/usr/bin $(1)/usr/lib/mergerfs
41 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/mount.mergerfs $(1)/sbin/
42 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mergerfs-fusermount $(1)/usr/bin/
43 | $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mergerfs $(1)/usr/bin/
44 | $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/mergerfs/preload.so $(1)/usr/lib/mergerfs/
45 | $(LN) /sbin/mount.mergerfs $(1)/sbin/fs/mount.mergerfs
46 |
47 | $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d $(1)/lib/fstab.d
48 | $(INSTALL_CONF) ./files/mergerfs.config $(1)/etc/config/mergerfs
49 | $(INSTALL_BIN) ./files/mergerfs.init $(1)/etc/init.d/mergerfs
50 | $(INSTALL_DATA) ./files/mergerfs.fstab $(1)/lib/fstab.d/mergerfs.sh
51 | endef
52 |
53 | # Set variables used in the source's Makefile
54 | MAKE_FLAGS+= NDEBUG=1 USE_XATTR=0 LTO=1 PREFIX=/usr
55 |
56 | $(eval $(call BuildPackage,mergerfs))
57 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/view/cpufreq/sandbox.htm:
--------------------------------------------------------------------------------
1 |
2 | <%+header%>
3 |
4 | <%:Sandbox%>
5 | <%:Simple sandbox for OpenWRT%>
6 |
7 | <%
8 |
9 | local sys = require "luci.sys"
10 |
11 | local insandbox = sys.call("/usr/sbin/sandbox status 2>/dev/null") == 0
12 |
13 | if insandbox then
14 | %>
15 |
16 |
17 | <% luci.template.render(translate("cpufreq/sb_info")) %>
18 |
19 |
20 |
21 |
22 |
55 |
56 |
61 |
62 |
63 |
64 | <%:Device is rebooting...%>
65 |
66 |
67 | <% else %>
68 |
69 |
70 | <% luci.template.render(translate("cpufreq/sb_guide")) %>
71 |
72 |
73 | <% end %>
74 |
75 | <%+footer%>
76 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/po/en/cpufreq.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | msgid "Tuning"
5 | msgstr "Tuning"
6 |
7 | msgid "CPU Tuning"
8 | msgstr "CPU Tuning"
9 |
10 | msgid "Manage CPU performance over LuCI."
11 | msgstr "Manage CPU performance over LuCI."
12 |
13 | msgid "CPU frequence:"
14 | msgstr "CPU frequence:"
15 |
16 | msgid "temperature:"
17 | msgstr "temperature:"
18 |
19 | msgid "CPUFreq governor"
20 | msgstr "CPUFreq governor"
21 |
22 | msgid "Default (Take effect after reboot)"
23 | msgstr "Default (Take effect after reboot)"
24 |
25 | msgid "conservative"
26 | msgstr "Conservative"
27 |
28 | msgid "userspace"
29 | msgstr "Userspace"
30 |
31 | msgid "powersave"
32 | msgstr "Powersave"
33 |
34 | msgid "ondemand"
35 | msgstr "Ondemand"
36 |
37 | msgid "performance"
38 | msgstr "Performance"
39 |
40 | msgid "interactive"
41 | msgstr "Interactive"
42 |
43 | msgid "Fan trigger temperature"
44 | msgstr "Fan trigger temperature"
45 |
46 | msgid "IPK Mirror"
47 | msgstr "IPK Mirror"
48 |
49 | msgid "Select IPK Mirror server"
50 | msgstr "Select IPK Mirror server"
51 |
52 | msgid "Mirror server"
53 | msgstr "Mirror server"
54 |
55 | msgid "Tsinghua University"
56 | msgstr "Tsinghua University"
57 |
58 | msgid "USTC"
59 | msgstr "USTC"
60 |
61 | msgid "Alibaba Cloud"
62 | msgstr "Alibaba Cloud"
63 |
64 | msgid "Tencent Cloud"
65 | msgstr "Tencent Cloud"
66 |
67 | msgid "Drivers"
68 | msgstr "Drivers"
69 |
70 | msgid "Drivers Settings"
71 | msgstr "Drivers Settings"
72 |
73 | msgid "Realtek r8125 driver"
74 | msgstr "Realtek r8125 driver"
75 |
76 | msgid "Realtek r8168 driver"
77 | msgstr "Realtek r8168 driver"
78 |
79 | msgid "Backported Intel GPU driver (i915-oot)"
80 | msgstr "Backported Intel GPU driver (i915-oot)"
81 |
82 | msgid "Enable additional drivers"
83 | msgstr "Enable additional drivers"
84 |
85 | msgid "Configure device drivers, kernel modules, etc. Changes here will take effect on next boot"
86 | msgstr "Configure device drivers, kernel modules, etc. Changes here will take effect on next boot"
87 |
88 | msgid "Please do not choose a driver you do not understand. Choosing the wrong driver may cause the system to fail to start"
89 | msgstr "Please do not choose a driver you do not understand. Choosing the wrong driver may cause the system to fail to start"
90 |
--------------------------------------------------------------------------------
/luci-app-fan/po/templates/luci-fan.pot:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:19
5 | msgid ""
6 | "Control fan start and stop temperature. This plugin can only configure the "
7 | "lowest gear, not necessarily applicable to all devices."
8 | msgstr ""
9 |
10 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:9
11 | msgid "Current temperature"
12 | msgstr ""
13 |
14 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:31
15 | msgid "Enabled"
16 | msgstr ""
17 |
18 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/controller/admin/luci-fan.lua:13
19 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:19
20 | msgid "Fan Control"
21 | msgstr ""
22 |
23 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:27
24 | msgid "Fan Settings"
25 | msgstr ""
26 |
27 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:34
28 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:8
29 | msgid "Fan start temperature"
30 | msgstr ""
31 |
32 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:42
33 | msgid "Fan stop temperature"
34 | msgstr ""
35 |
36 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:80
37 | msgid "Fan stop temperature MUST be lower than fan start temperature"
38 | msgstr ""
39 |
40 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:42
41 | msgid ""
42 | "Optional, MUST be lower than the fan start temperature. Default fan start "
43 | "temperature minus 5 ℃"
44 | msgstr ""
45 |
46 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:3
47 | msgid "Status"
48 | msgstr ""
49 |
50 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:6
51 | msgid "Thermal zone"
52 | msgstr ""
53 |
54 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:7
55 | msgid "Trip point"
56 | msgstr ""
57 |
58 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:31
59 | msgid "Whether to apply the settings"
60 | msgstr ""
61 |
62 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:6
63 | msgid "type:"
64 | msgstr ""
65 |
--------------------------------------------------------------------------------
/mergerfs/files/mergerfs.init:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | # mergerfs -f -o category.create=epmfs,minfreespace=100M,fsname=mergerfs:/mnt/merged /mnt/n2:/mnt/n3:/mnt/n4 /mnt/merged
4 |
5 | START=98
6 |
7 | USE_PROCD=1
8 |
9 | start_service() {
10 | config_load mergerfs
11 | config_foreach start_pool pool
12 | }
13 |
14 | start_pool() {
15 | local section="$1"
16 | local enabled mountpoint paths createpolicy minfreespace options
17 |
18 | config_get_bool enabled "$section" enabled 0
19 | [ "$enabled" -eq 1 ] || return 0
20 | config_get mountpoint "$section" mountpoint
21 | config_get paths "$section" paths
22 | config_get createpolicy "$section" createpolicy "epmfs"
23 | config_get minfreespace "$section" minfreespace "4G"
24 | config_get options "$section" options
25 |
26 | # 检查 mountpoint 是否已设置
27 | [ -z "$mountpoint" ] && {
28 | logger -t "mergerfs" "mountpoint not set for $section"
29 | return 1
30 | }
31 |
32 | # (
33 | printf "%s\n" "$paths" | while IFS= read -r p; do
34 | case "$p" in
35 | /*)
36 | if [ ! -d "$p" ]; then
37 | logger -t "mergerfs" "source path $p does not exist for $mountpoint"
38 | return 1
39 | fi
40 | ;;
41 | esac
42 | done || return 1
43 |
44 | # 只保留以 / 开头的路径,拼接为冒号分隔的字符串
45 | srcs=$(
46 | # (
47 | printf "%s\n" "$paths" | while IFS= read -r p; do
48 | case "$p" in
49 | /*) printf ':%s' "$p" ;;
50 | esac
51 | done
52 | )
53 | srcs="${srcs#:}"
54 |
55 | [ -z "$srcs" ] && {
56 | logger -t "mergerfs" "no valid source paths for $mountpoint"
57 | return 1
58 | }
59 |
60 | local opts
61 | opts="category.create=${createpolicy},minfreespace=${minfreespace},fsname=mergerfs:${mountpoint}"
62 | [ -n "$options" ] && opts="${opts},${options}"
63 |
64 | mkdir -p "$mountpoint"
65 | # mountpoint -q "$mountpoint" && umount "$mountpoint"
66 |
67 | logger -t "mergerfs" "mergerfs -o $opts \"$srcs\" \"$mountpoint\""
68 |
69 | procd_open_instance "$section"
70 | procd_set_param command /usr/bin/mergerfs -f -o "$opts" "$srcs" "$mountpoint"
71 | procd_close_instance
72 | # close flock fd, or the script will hangs next time it runs
73 | # ( exec 1000>&- ; mergerfs -o "$opts" "$srcs" "$mountpoint" )
74 | }
75 |
76 | stop_service() {
77 | config_load mergerfs
78 | config_foreach stop_pool pool
79 | }
80 |
81 | stop_pool() {
82 | local section="$1"
83 | local mountpoint
84 | config_get mountpoint "$section" mountpoint
85 | [ -n "$mountpoint" ] && umount "$mountpoint"
86 | }
87 |
88 | service_triggers() {
89 | procd_add_reload_trigger "mergerfs"
90 | }
91 |
--------------------------------------------------------------------------------
/luci-app-fan/po/zh-cn/luci-fan.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Language: zh_Hans\n"
4 | "Content-Type: text/plain; charset=UTF-8\n"
5 | "Content-Transfer-Encoding: 8bit\n"
6 | "Plural-Forms: nplurals=1; plural=0;\n"
7 |
8 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:19
9 | msgid ""
10 | "Control fan start and stop temperature. This plugin can only configure the "
11 | "lowest gear, not necessarily applicable to all devices."
12 | msgstr "控制风扇启停温度。此插件仅配置最低档位触发点,不一定适用于所有设备"
13 |
14 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:9
15 | msgid "Current temperature"
16 | msgstr "当前温度"
17 |
18 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:31
19 | msgid "Enabled"
20 | msgstr "启用"
21 |
22 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/controller/admin/luci-fan.lua:13
23 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:19
24 | msgid "Fan Control"
25 | msgstr "风扇控制"
26 |
27 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:27
28 | msgid "Fan Settings"
29 | msgstr "风扇设置"
30 |
31 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:34
32 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:8
33 | msgid "Fan start temperature"
34 | msgstr "风扇启动温度"
35 |
36 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:42
37 | msgid "Fan stop temperature"
38 | msgstr "风扇停止温度"
39 |
40 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:80
41 | msgid "Fan stop temperature MUST be lower than fan start temperature"
42 | msgstr "风扇停止温度必须小于风扇启动温度"
43 |
44 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:42
45 | msgid ""
46 | "Optional, MUST be lower than the fan start temperature. Default fan start "
47 | "temperature minus 5 ℃"
48 | msgstr "可选,必须小于风扇启动温度。默认风扇启动温度减 5 ℃"
49 |
50 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:3
51 | msgid "Status"
52 | msgstr "状态"
53 |
54 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:6
55 | msgid "Thermal zone"
56 | msgstr "温感区"
57 |
58 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:7
59 | msgid "Trip point"
60 | msgstr "触发点"
61 |
62 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/model/cbi/luci-fan.lua:31
63 | msgid "Whether to apply the settings"
64 | msgstr "是否应用此设置"
65 |
66 | #: /Volumes/data/src/nas-packages-luci/luci/luci-app-fan/luasrc/view/luci-fan.htm:6
67 | msgid "type:"
68 | msgstr "类型:"
69 |
--------------------------------------------------------------------------------
/homebox/Makefile:
--------------------------------------------------------------------------------
1 | include $(TOPDIR)/rules.mk
2 |
3 | PKG_NAME:=homebox
4 | PKG_VERSION:=0.0.0_pre2020062901
5 | PKG_RELEASE:=3
6 |
7 | SRC_VERSION:=0.0.0-dev.2020062901
8 | PKG_SOURCE_URL_FILE:=v$(SRC_VERSION).tar.gz
9 | PKG_SOURCE:=$(PKG_NAME)-$(SRC_VERSION).tar.gz
10 | PKG_SOURCE_URL:=https://github.com/XGHeaven/homebox/archive/refs/tags/
11 | PKG_HASH:=815a2a0fc5458245769648ef5b394f69fdec2573a1403b789146be0c4217a443
12 |
13 | PKG_BUILD_DEPENDS:=golang/host homebox/host
14 | PKG_BUILD_PARALLEL:=1
15 | PKG_USE_MIPS16:=0
16 |
17 | HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}
18 |
19 | include $(INCLUDE_DIR)/host-build.mk
20 | include $(INCLUDE_DIR)/package.mk
21 | include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
22 |
23 | define Package/$(PKG_NAME)
24 | SECTION:=net
25 | CATEGORY:=Network
26 | SUBMENU:=Web Servers/Proxies
27 | TITLE:=A Toolbox for Home Local Networks
28 | URL:=https://github.com/XGHeaven/homebox
29 | DEPENDS:=$(GO_ARCH_DEPENDS)
30 | MENU:=1
31 | endef
32 |
33 | define Package/$(PKG_NAME)/description
34 | A Toolbox for Home Local Networks Speed Test
35 | endef
36 |
37 | GO_PKG_BUILD_VARS += GO111MODULE=auto
38 | TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS)
39 | TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
40 |
41 | define Build/Configure
42 | ( \
43 | cd $(PKG_BUILD_DIR)/server; \
44 | $(GO_PKG_VARS) \
45 | go get -d -modcacherw; \
46 | )
47 | ( \
48 | cd $(PKG_BUILD_DIR)/server; \
49 | GOPATH=$(PKG_BUILD_DIR)/.go_work/build \
50 | go install -modcacherw github.com/go-bindata/go-bindata/...@latest; \
51 | )
52 | endef
53 |
54 | define Build/Compile
55 | rm -rf $(PKG_BUILD_DIR)/build/static
56 | mkdir -p $(PKG_BUILD_DIR)/build
57 | $(CP) $(HOST_BUILD_DIR)/build/static $(PKG_BUILD_DIR)/build/
58 | ( \
59 | cd $(PKG_BUILD_DIR); \
60 | $(GO_PKG_VARS) PATH=$(PKG_BUILD_DIR)/.go_work/build/bin:$$$$PATH \
61 | $(MAKE) build-server; \
62 | )
63 | endef
64 |
65 | define Package/$(PKG_NAME)/install
66 | $(INSTALL_DIR) $(1)/usr/bin $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults
67 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/server $(1)/usr/bin/homebox
68 | $(INSTALL_CONF) ./files/homebox.config $(1)/etc/config/homebox
69 | $(INSTALL_BIN) ./files/homebox.init $(1)/etc/init.d/homebox
70 | $(INSTALL_BIN) ./files/homebox.uci-default $(1)/etc/uci-defaults/homebox
71 | endef
72 |
73 | define Package/$(PKG_NAME)/conffiles
74 | /etc/config/homebox
75 | endef
76 |
77 | define Package/$(PKG_NAME)/postinst
78 | #!/bin/sh
79 | if [ -z "$${IPKG_INSTROOT}" ]; then
80 | [ -f /etc/uci-defaults/homebox ] && /etc/uci-defaults/homebox && rm -f /etc/uci-defaults/homebox
81 | exit 0
82 | fi
83 | endef
84 |
85 | define Host/Configure
86 | cd $(HOST_BUILD_DIR)/web && rm -f package-lock.json && npm --cache-min 1440 install
87 | endef
88 |
89 | define Host/Compile
90 | cd $(HOST_BUILD_DIR) && $(MAKE) build-web
91 | endef
92 |
93 | define Host/Install
94 | endef
95 |
96 | define Host/Clean
97 | rm -f $(HOST_BUILD_DIR)/build/static
98 | endef
99 |
100 | $(eval $(call HostBuild))
101 | $(eval $(call BuildPackage,homebox))
102 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/po/templates/cpufreq.pot:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | msgid "Tuning"
5 | msgstr ""
6 |
7 | msgid "CPU Tuning"
8 | msgstr ""
9 |
10 | msgid "Manage CPU performance over LuCI."
11 | msgstr ""
12 |
13 | msgid "CPU frequence:"
14 | msgstr ""
15 |
16 | msgid "temperature:"
17 | msgstr ""
18 |
19 | msgid "CPUFreq governor"
20 | msgstr ""
21 |
22 | msgid "Default (Take effect after reboot)"
23 | msgstr ""
24 |
25 | msgid "conservative"
26 | msgstr ""
27 |
28 | msgid "userspace"
29 | msgstr ""
30 |
31 | msgid "powersave"
32 | msgstr ""
33 |
34 | msgid "ondemand"
35 | msgstr ""
36 |
37 | msgid "performance"
38 | msgstr ""
39 |
40 | msgid "interactive"
41 | msgstr ""
42 |
43 | msgid "schedutil"
44 | msgstr ""
45 |
46 | msgid "It is recommended to use 'ondemand' or 'schedutil'"
47 | msgstr ""
48 |
49 | msgid "Frequency"
50 | msgstr ""
51 |
52 | msgid "Pay attention to heat dissipation when choosing high frequency"
53 | msgstr ""
54 |
55 | msgid "Fan trigger temperature"
56 | msgstr ""
57 |
58 | msgid "Fan temperature hysteresis"
59 | msgstr ""
60 |
61 | msgid "Set a larger value to avoid frequent restart of the fan"
62 | msgstr ""
63 |
64 | msgid "IPK Mirror"
65 | msgstr ""
66 |
67 | msgid "Select IPK Mirror server"
68 | msgstr ""
69 |
70 | msgid "Mirror server"
71 | msgstr ""
72 |
73 | msgid "Tsinghua University"
74 | msgstr ""
75 |
76 | msgid "USTC"
77 | msgstr ""
78 |
79 | msgid "Alibaba Cloud"
80 | msgstr ""
81 |
82 | msgid "Tencent Cloud"
83 | msgstr ""
84 |
85 | msgid "Boot"
86 | msgstr ""
87 |
88 | msgid "Delay before mounting"
89 | msgstr ""
90 |
91 | msgid "Timeout (seconds)"
92 | msgstr ""
93 |
94 | msgid "Or until these device(s) ready (UUID):"
95 | msgstr ""
96 |
97 | msgid "Samba expert"
98 | msgstr ""
99 |
100 | msgid "Allow legacy protocols"
101 | msgstr ""
102 |
103 | msgid "Allow old client, don't use this option for secure environments!"
104 | msgstr ""
105 |
106 | msgid "Sandbox"
107 | msgstr ""
108 |
109 | msgid "Simple sandbox for OpenWRT"
110 | msgstr ""
111 |
112 | msgid "This action will reboot device"
113 | msgstr ""
114 |
115 | msgid "Commit"
116 | msgstr ""
117 |
118 | msgid "Reset"
119 | msgstr ""
120 |
121 | msgid "cpufreq/sb_info"
122 | msgstr ""
123 |
124 | msgid "cpufreq/sb_guide"
125 | msgstr ""
126 |
127 | msgid "Network"
128 | msgstr ""
129 |
130 | msgid "Hardware Acceleration"
131 | msgstr ""
132 |
133 | msgid "Enable PPPoE Acceleration"
134 | msgstr ""
135 |
136 | msgid "Improve PPPoE TX performace, only support built-in NICs"
137 | msgstr ""
138 |
139 | msgid "Exit Sandbox"
140 | msgstr ""
141 |
142 | msgid "Enable WAN Port Acceleration"
143 | msgstr ""
144 |
145 | msgid "Improve built-in WAN port (eth0) TX performace"
146 | msgstr ""
147 |
148 | msgid "Drivers"
149 | msgstr ""
150 |
151 | msgid "Drivers Settings"
152 | msgstr ""
153 |
154 | msgid "Realtek r8125 driver"
155 | msgstr ""
156 |
157 | msgid "Realtek r8168 driver"
158 | msgstr ""
159 |
160 | msgid "Backported Intel GPU driver (i915-oot)"
161 | msgstr ""
162 |
163 | msgid "Enable additional drivers"
164 | msgstr ""
165 |
166 | msgid "Configure device drivers, kernel modules, etc. Changes here will take effect on next boot"
167 | msgstr ""
168 |
169 | msgid "Please do not choose a driver you do not understand. Choosing the wrong driver may cause the system to fail to start"
170 | msgstr ""
171 |
--------------------------------------------------------------------------------
/luci-app-fan/luasrc/model/cbi/luci-fan.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2023 jjm2473
4 | ]]--
5 |
6 | local m, s, o
7 | require "luci.util"
8 |
9 | local fs = require "nixio.fs"
10 |
11 | local sys = require "luci.sys"
12 |
13 | local words = luci.util.split(luci.util.trim(sys.exec("/usr/libexec/fan-control get 2>/dev/null")), " ")
14 |
15 | if #words < 3 then
16 | return
17 | end
18 |
19 | m = Map("luci-fan", translate("Fan Control"), translate("Control fan start and stop temperature. This plugin can only configure the lowest gear, not necessarily applicable to all devices."))
20 |
21 | s = m:section(SimpleSection)
22 | s.template = "luci-fan"
23 | s.thermal_zone = words[1]
24 | s.trip_point = words[2]
25 | s.thermal_type = luci.util.trim(fs.readfile("/sys/class/thermal/"..words[1].."/type"))
26 |
27 | s = m:section(TypedSection, "luci-fan", translate("Fan Settings"))
28 | s.addremove = false
29 | s.anonymous = true
30 |
31 | o = s:option(Flag, "enabled", translate("Enabled"), translate("Whether to apply the settings"))
32 | o.default = 0
33 |
34 | local on_temp = s:option(Value, "on_temp", translate("Fan start temperature") .. " (℃)")
35 | on_temp.datatype = "and(uinteger,min(5))"
36 | on_temp.rmempty = false
37 | on_temp.default = math.floor(tonumber(words[3])/1000)
38 | if #words > 3 then
39 | on_temp.datatype = string.format("and(uinteger,range(5,%u))", math.floor(tonumber(words[4])/1000 - 1))
40 | end
41 |
42 | o = s:option(Value, "off_temp", translate("Fan stop temperature") .. " (℃)", translate("Optional, MUST be lower than the fan start temperature. Default fan start temperature minus 5 ℃"))
43 | o.datatype = "uinteger"
44 | o.rmempty = true
45 | function o.parse(self, section, novld)
46 | local fvalue = self:formvalue(section)
47 | local fexist = ( fvalue and (#fvalue > 0) ) -- not "nil" and "not empty"
48 |
49 | local vvalue, errtxt = self:validate(fvalue)
50 | if not vvalue then
51 | if novld then -- and "novld" set
52 | return -- then exit without raising an error
53 | end
54 | if fexist then -- and there is a formvalue
55 | self:add_error(section, "invalid", errtxt or self.title .. ": invalid")
56 | return -- so data are invalid
57 | end
58 | end
59 | local rm_opt = ( self.rmempty or self.optional )
60 | local vexist = ( vvalue and (#vvalue > 0) ) and true or false -- not "nil" and "not empty"
61 | local eq_def = ( vvalue == self.default ) -- equal_default flag
62 | -- (rmempty or optional) and (no data or equal_default)
63 | if rm_opt and (not vexist or eq_def) then
64 | if self:remove(section) then -- remove data from UCI
65 | self.section.changed = true -- and push events
66 | end
67 | return
68 | end
69 |
70 | local cvalue = self:cfgvalue(section)
71 | local eq_cfg = ( vvalue == cvalue ) -- update equal_config flag
72 | -- not forcewrite and no changes, so nothing to write
73 | if not self.forcewrite and eq_cfg then
74 | return
75 | end
76 |
77 | local onvalue = on_temp:validate(on_temp:formvalue(section))
78 | if onvalue and #onvalue > 0 then
79 | if tonumber(vvalue) >= tonumber(onvalue) then
80 | self:add_error(section, "invalid", translate("Fan stop temperature MUST be lower than fan start temperature"))
81 | return
82 | end
83 | else
84 | return
85 | end
86 |
87 | -- write data to UCI; raise event only on changes
88 | if self:write(section, vvalue) and not eq_cfg then
89 | self.section.changed = true
90 | end
91 | end
92 |
93 | return m
94 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/luasrc/controller/admin/cpufreq.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | LuCI - Lua Configuration Interface
3 | Copyright 2021 jjm2473
4 | ]]--
5 |
6 | module("luci.controller.admin.cpufreq",package.seeall)
7 | require "luci.util"
8 |
9 | function index()
10 | local sys = require "luci.sys"
11 | local appname = "tuning"
12 | local defaultpage = nil
13 | entry({"admin", "system", appname}).dependent = true
14 | if nixio.fs.access("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq") then
15 | defaultpage = defaultpage or alias("admin", "system", appname, "main")
16 | entry({"admin", "system", appname, "main"}, cbi("cpufreq/main"), _("CPU Tuning"), 1).leaf = true
17 | entry({"admin", "system", appname, "get_cpu_info"}, call("get_cpu_info"), nil).leaf = true
18 | end
19 | if nixio.fs.access("/rom/etc/opkg/distfeeds.conf") then
20 | defaultpage = defaultpage or alias("admin", "system", appname, "ipk")
21 | entry({"admin", "system", appname, "ipk"}, cbi("cpufreq/ipk"), _("IPK Mirror"), 2).leaf = true
22 | end
23 | if nixio.fs.access("/etc/config/samba4") then
24 | defaultpage = defaultpage or alias("admin", "system", appname, "samba")
25 | entry({"admin", "system", appname, "samba"}, cbi("cpufreq/samba"), _("Samba"), 3).leaf = true
26 | end
27 | defaultpage = defaultpage or alias("admin", "system", appname, "boot")
28 | entry({"admin", "system", appname, "boot"}, cbi("cpufreq/boot"), _("Boot"), 4).leaf = true
29 |
30 | if nixio.fs.access("/etc/config/kmods") and sys.call("[ -n \"$(ls /etc/modules-pending.d/ 2>/dev/null | head -c1)\" ] >/dev/null 2>&1") == 0 then
31 | entry({"admin", "system", appname, "kmods"}, cbi("cpufreq/kmods"), _("Drivers"), 5).leaf = true
32 | end
33 |
34 | if sys.call("[ -d /ext_overlay ] >/dev/null 2>&1") == 0 then
35 | entry({"admin", "system", appname, "sandbox"}, call("sandbox_index",
36 | {prefix=luci.dispatcher.build_url("admin", "system", appname, "sandbox")}), _("Sandbox"), 6)
37 | entry({"admin", "system", appname, "sandbox", "reset"}, post("sandbox_reset"))
38 | entry({"admin", "system", appname, "sandbox", "commit"}, post("sandbox_commit"))
39 | entry({"admin", "system", appname, "sandbox", "exit"}, post("sandbox_exit"))
40 | end
41 |
42 | local hwppoe_feature = luci.util.trim(sys.exec("ethtool -k eth0 2>/dev/null | grep -F hw-pppoe: 2>/dev/null"))
43 | if hwppoe_feature ~= nil and hwppoe_feature ~= "" and not string.match(hwppoe_feature, "%[fixed%]") then
44 | entry({"admin", "system", appname, "net"}, cbi("cpufreq/net"), _("Network"), 7).leaf = true
45 | end
46 |
47 | if nixio.fs.access("/etc/init.d/grub") then
48 | entry({"admin", "system", appname, "cmdline"}, cbi("cpufreq/cmdline"), _("Kernel Cmdline"), 8).leaf = true
49 | end
50 |
51 | if defaultpage then
52 | entry({"admin", "system", appname}, defaultpage, _("Tuning"), 59)
53 | end
54 |
55 | end
56 |
57 | function get_cpu_info()
58 | local fs = require "nixio.fs"
59 | local freq = tonumber(fs.readfile("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq")) / 1000; -- MHz
60 | luci.http.status(200, "ok")
61 | luci.http.prepare_content("application/json")
62 | luci.http.write_json({freq=freq})
63 | end
64 |
65 | function sandbox_index(param)
66 | luci.template.render("cpufreq/sandbox", {prefix=param.prefix})
67 | end
68 |
69 | function sandbox_reset()
70 | local sys = require "luci.sys"
71 | sys.call("/usr/sbin/sandbox reset")
72 | luci.sys.reboot()
73 | end
74 |
75 | function sandbox_commit()
76 | local sys = require "luci.sys"
77 | sys.call("/usr/sbin/sandbox commit")
78 | luci.sys.reboot()
79 | end
80 |
81 | function sandbox_exit()
82 | local sys = require "luci.sys"
83 | sys.call("/usr/sbin/sandbox exit")
84 | luci.sys.reboot()
85 | end
86 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/po/zh_Hans/mergerfs.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Language: zh_Hans\n"
4 | "Content-Type: text/plain; charset=UTF-8\n"
5 | "Content-Transfer-Encoding: 8bit\n"
6 | "Plural-Forms: nplurals=1; plural=0;\n"
7 |
8 | msgid "Create policy"
9 | msgstr "创建策略"
10 |
11 | msgid "Each line must be a path starting with a '/' or be a comment starting with '#'."
12 | msgstr "每行必须是以'/'开头的路径或者以'#'开头的注释。"
13 |
14 | msgid "Existing path - all"
15 | msgstr "现有路径 - 全部"
16 |
17 | msgid "Existing path - first found"
18 | msgstr "现有路径 - 第一个找到的"
19 |
20 | msgid "Existing path - least free space"
21 | msgstr "现有路径 - 最少可用空间"
22 |
23 | msgid "Existing path - least used space"
24 | msgstr "现有路径 - 最少已用空间"
25 |
26 | msgid "Existing path - most free space"
27 | msgstr "现有路径 - 最多可用空间"
28 |
29 | msgid "Existing path - percentage free random distribution"
30 | msgstr "现有路径 - 按可用空间百分比随机分布"
31 |
32 | msgid "Existing path - random"
33 | msgstr "现有路径 - 随机"
34 |
35 | msgid "Failed to unmount"
36 | msgstr "卸载失败"
37 |
38 | msgid "First found"
39 | msgstr "第一个找到的"
40 |
41 | msgid "If mounting fails, search \"mergerfs\" in the system log for more information."
42 | msgstr "如果挂载失败,在系统日志中搜索\"mergerfs\"以获取信息。"
43 |
44 | msgid "Least free space"
45 | msgstr "最少可用空间"
46 |
47 | msgid "Least used space"
48 | msgstr "最少已用空间"
49 |
50 | msgid "List of paths to merge, one per line. Line starting with '#' will be treated as a comment.
All paths must existed before mounting or the mounting will fail."
51 | msgstr "要合并的路径列表,每行一个路径。以'#'开头的行将被视为注释。
挂载前所有路径必须存在,否则挂载将失败。"
52 |
53 | msgid "MergerFS Pool"
54 | msgstr "MergerFS 存储池"
55 |
56 | msgid "MergerFS is a union filesystem, which allows you to pool multiple directories into a single mount point.
This is useful for combining storage space and files from multiple devices or directories into one accessible location.
New files can be distributed across the pooled directories based on various policies, such as most free space or first found.
More information can be found at GitHub."
57 | msgstr "MergerFS 是一个联合文件系统,允许您将多个目录池化到一个挂载点。
这对于将来自多个设备或目录的存储空间和文件合并到一个可访问的位置很有用。
新文件可以根据各种策略(如最多可用空间或第一个找到的)分布在池化的目录中。
更多信息可以在 GitHub 找到。"
58 |
59 | msgid "Minimum free space"
60 | msgstr "最小可用空间"
61 |
62 | msgid "Most free space"
63 | msgstr "最多可用空间"
64 |
65 | msgid "Most shared path - least free space"
66 | msgstr "最多共享路径 - 最少可用空间"
67 |
68 | msgid "Most shared path - least used space"
69 | msgstr "最多共享路径 - 最少已用空间"
70 |
71 | msgid "Most shared path - most free space"
72 | msgstr "最多共享路径 - 最多可用空间"
73 |
74 | msgid "Most shared path - percentage free random distribution"
75 | msgstr "最多共享路径 - 按可用空间百分比随机分布"
76 |
77 | msgid "Mount Configured MergerFS"
78 | msgstr "挂载已配置的 MergerFS"
79 |
80 | msgid "Mount to this path"
81 | msgstr "挂载到此路径"
82 |
83 | msgid "Mounted MergerFS"
84 | msgstr "已挂载的 MergerFS"
85 |
86 | msgid "No mounted MergerFS found"
87 | msgstr "未找到已挂载的 MergerFS"
88 |
89 | msgid "Mount Point is required, must start with \"/\" and cannot be root \"/\""
90 | msgstr "挂载点是必需的,必须以\"/\"开头且不能是根目录\"/\""
91 |
92 | msgid "Newest file"
93 | msgstr "最新文件"
94 |
95 | msgid "Options"
96 | msgstr "选项"
97 |
98 | msgid "Paths"
99 | msgstr "路径"
100 |
101 | msgid "Percentage free random distribution"
102 | msgstr "按可用空间百分比随机分布"
103 |
104 | msgid "Please enter a value like 4G, 500M, 100K"
105 | msgstr "请输入类似 4G, 500M, 100K 的值"
106 |
107 | msgid "Policy for creating new files"
108 | msgstr "创建新文件的策略"
109 |
110 | msgid "Pool Settings"
111 | msgstr "存储池设置"
112 |
113 | msgid "Put each folder on a new line."
114 | msgstr "每行放一个文件夹。"
115 |
116 | msgid "Random"
117 | msgstr "随机"
118 |
119 | msgid "Read-only"
120 | msgstr "只读"
121 |
122 | msgid "You must provide at least one valid path (not a comment or empty line)."
123 | msgstr "您必须提供至少一个有效路径(不是注释或空行)。"
124 |
--------------------------------------------------------------------------------
/luci-app-fan/root/usr/libexec/fan-control:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # author: jjm2473
3 |
4 | SAVE=/tmp/run/fanTP
5 | ACTION=${1}
6 | shift
7 |
8 | # print: zone trip_point current_target_temp [max_target_temp]
9 | # ex. thermal_zone0 0 50000 60000
10 | function getFanTP() {
11 | local zone cdev trip temp mintemp mintrip minzone maxtemp
12 | [[ -d /sys/class/thermal ]] || return 1
13 | cd /sys/class/thermal
14 | for zone in thermal_zone* ; do
15 | cd "$zone"
16 | for cdev in `ls | grep 'cdev[0-9]\+$'`; do
17 | [[ -d "$cdev" ]] || continue
18 | grep -Fiq fan "$cdev/type" || continue
19 | trip=`cat ${cdev}_trip_point`
20 | grep -Fwq active trip_point_${trip}_type || continue
21 | [[ "`stat -c '%#a' trip_point_${trip}_temp || echo 0444`" = "0644" ]] || continue
22 | temp=`cat trip_point_${trip}_temp`
23 | if [[ -z "$mintemp" ]] || [[ "$temp" -lt "$mintemp" ]]; then
24 | if [[ -n "$mintemp" ]]; then
25 | if [[ "$zone" = "$minzone" ]]; then
26 | maxtemp=$mintemp
27 | else
28 | maxtemp=
29 | fi
30 | fi
31 | mintemp=$temp
32 | mintrip=$trip
33 | minzone=$zone
34 | elif [[ -z "$maxtemp" ]] || [[ "$temp" -lt "$maxtemp" ]]; then
35 | maxtemp=$temp
36 | fi
37 | done
38 | cd /sys/class/thermal
39 | done
40 | if [[ -n "$mintemp" ]]; then
41 | echo "$minzone" "$mintrip" "$mintemp" $maxtemp
42 | return 0
43 | else
44 | return 1
45 | fi
46 | }
47 |
48 | function getFanTP_C() {
49 | if [[ -f "$SAVE" ]]; then
50 | if [[ -s "$SAVE" ]]; then
51 | cat "$SAVE"
52 | return 0
53 | else
54 | return 1
55 | fi
56 | fi
57 | ( getFanTP ) | tee "$SAVE"
58 | [[ -s "$SAVE" ]]
59 | }
60 |
61 | function getFanTP_U() {
62 | set $(getFanTP_C)
63 | [[ -n "$1" && -n "$2" ]] || return 1
64 | local onTemp=`cat "/sys/class/thermal/${1}/trip_point_${2}_temp"`
65 | echo "$1" "$2" "$onTemp" $4
66 | return 0
67 | }
68 |
69 | function initFanTP() {
70 | [[ -f "$SAVE" ]] || ( getFanTP >"$SAVE" )
71 | }
72 |
73 | # param: ON_TEMP [OFF_TEMP]
74 | # OFF_TEMP = ON_TEMP - 5000 if not set
75 | # ex. 60000 55000
76 | function setFanTP() {
77 | local ON_TEMP=$1
78 | local OFF_TEMP=$2
79 | [[ -n "$ON_TEMP" ]] || {
80 | echo "ON_TEMP must be present" >&2
81 | return 1
82 | }
83 | if [[ -z "$OFF_TEMP" ]]; then
84 | [[ "$ON_TEMP" -gt 5000 ]] || {
85 | echo "ON_TEMP must greater than 5000 when OFF_TEMP not present" >&2
86 | return 1
87 | }
88 | OFF_TEMP=$(( $ON_TEMP - 5000 ))
89 | fi
90 | [[ "$ON_TEMP" -gt "$OFF_TEMP" ]] || {
91 | echo "ON_TEMP must greater than OFF_TEMP" >&2
92 | return 1
93 | }
94 | local HYST=$(( $ON_TEMP - $OFF_TEMP ))
95 |
96 | set $(getFanTP_C)
97 | [[ -n "$1" && -n "$2" ]] || return 1
98 | [[ -d "/sys/class/thermal/${1}" ]] || return 1
99 |
100 | [[ -n "$4" ]] && [[ "$ON_TEMP" -ge "$4" ]] && {
101 | ON_TEMP=$(( $4 - 5000 ))
102 | echo "WARN: ON_TEMP greater than next TP $4, fixed to $ON_TEMP" >&2
103 | }
104 | echo "$ON_TEMP" > "/sys/class/thermal/${1}/trip_point_${2}_temp"
105 | echo "$HYST" > "/sys/class/thermal/${1}/trip_point_${2}_hyst"
106 | }
107 |
108 | # print: current thermal sensor value and fan on temp
109 | function getTemp() {
110 | set $(getFanTP_C)
111 | [[ -n "$1" && -n "$2" ]] || return 1
112 | [[ -f "/sys/class/thermal/$1/temp" ]] || return 1
113 | local temp=`cat "/sys/class/thermal/$1/temp"`
114 | local tpt=`cat "/sys/class/thermal/$1/trip_point_${2}_temp"`
115 | echo "$temp $tpt"
116 | }
117 |
118 | usage() {
119 | echo "usage: $0 sub-command"
120 | echo "where sub-command is one of:"
121 | echo " get Get Fan setting"
122 | echo " set ON_TEMP [OFF_TEMP] Set Fan setting"
123 | echo " temp Get current thermal temp and Fan on temp"
124 | echo " init init, internal used"
125 | }
126 |
127 | case ${ACTION} in
128 | "get")
129 | getFanTP_U
130 | ;;
131 | "set")
132 | setFanTP "$@"
133 | ;;
134 | "temp")
135 | getTemp
136 | ;;
137 | "init")
138 | initFanTP
139 | ;;
140 | *)
141 | usage
142 | exit 1
143 | ;;
144 | esac
145 |
146 |
--------------------------------------------------------------------------------
/luci-app-cpufreq/po/zh-cn/cpufreq.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8"
3 |
4 | msgid "Tuning"
5 | msgstr "杂项设置"
6 |
7 | msgid "CPU Tuning"
8 | msgstr "CPU调节"
9 |
10 | msgid "Manage CPU performance over LuCI."
11 | msgstr "通过LuCI调节CPU性能"
12 |
13 | msgid "CPU frequence:"
14 | msgstr "CPU频率:"
15 |
16 | msgid "temperature:"
17 | msgstr "核心温度:"
18 |
19 | msgid "CPUFreq governor"
20 | msgstr "CPU性能策略"
21 |
22 | msgid "Apply"
23 | msgstr "应用"
24 |
25 | msgid "Default (Take effect after reboot)"
26 | msgstr "默认(重启后生效)"
27 |
28 | msgid "conservative"
29 | msgstr "Conservative(平滑)"
30 |
31 | msgid "userspace"
32 | msgstr "手动/固定频率"
33 |
34 | msgid "powersave"
35 | msgstr "节能模式"
36 |
37 | msgid "ondemand"
38 | msgstr "自动调节"
39 |
40 | msgid "performance"
41 | msgstr "性能模式"
42 |
43 | msgid "interactive"
44 | msgstr "Interactive(灵敏)"
45 |
46 | msgid "schedutil"
47 | msgstr "基于调度器"
48 |
49 | msgid "It is recommended to use 'ondemand' or 'schedutil'"
50 | msgstr "推荐使用“自动调节”或“基于调度器”"
51 |
52 | msgid "Frequency"
53 | msgstr "频率"
54 |
55 | msgid "Pay attention to heat dissipation when choosing high frequency"
56 | msgstr "选择高频时注意散热"
57 |
58 | msgid "Fan trigger temperature"
59 | msgstr "风扇启动温度"
60 |
61 | msgid "Fan temperature hysteresis"
62 | msgstr "风扇温度容错"
63 |
64 | msgid "Set a larger value to avoid frequent restart of the fan"
65 | msgstr "设置更大的值以避免频繁重启风扇"
66 |
67 | msgid "IPK Mirror"
68 | msgstr "IPK镜像服务器"
69 |
70 | msgid "Select IPK Mirror server"
71 | msgstr "选择IPK镜像服务器"
72 |
73 | msgid "Mirror server"
74 | msgstr "镜像服务器"
75 |
76 | msgid "Tsinghua University"
77 | msgstr "清华大学"
78 |
79 | msgid "USTC"
80 | msgstr "中国科学技术大学"
81 |
82 | msgid "Alibaba Cloud"
83 | msgstr "阿里云"
84 |
85 | msgid "Tencent Cloud"
86 | msgstr "腾讯云"
87 |
88 | msgid "CERNET 302"
89 | msgstr "高校联合镜像站(智能选择最近大学镜像站)"
90 |
91 | msgid "SUSTech"
92 | msgstr "南方科技大学"
93 |
94 | msgid "Lanzhou University"
95 | msgstr "兰州大学"
96 |
97 | msgid "Chinese Academy of Sciences"
98 | msgstr "中国科学院"
99 |
100 | msgid "NYIST"
101 | msgstr "南洋理工大学"
102 |
103 | msgid "SJTU"
104 | msgstr "上海交通大学"
105 |
106 | msgid "CQUPT"
107 | msgstr "重庆邮电大学"
108 |
109 | msgid "Qilu University of Technology"
110 | msgstr "齐鲁工业大学"
111 |
112 | msgid "Boot"
113 | msgstr "启动"
114 |
115 | msgid "Delay before disk mounting"
116 | msgstr "挂载前等待磁盘"
117 |
118 | msgid "Wait for the hard disk to initialize to solve the problem that the hard disk is not mounted when some applications that rely on the hard disk are started."
119 | msgstr "等待硬盘初始化,以解决部分依赖硬盘的应用启动时硬盘还未挂载的问题"
120 |
121 | msgid "Do not select a network block device (e.g. NBD, iSCSI, etc.), you may have to wait until timeout."
122 | msgstr "请勿选择网络块设备(例如 NBD,iSCSI 等),可能必须等到超时"
123 |
124 | msgid "Timeout (seconds)"
125 | msgstr "超时(秒)"
126 |
127 | msgid "Or until these device(s) ready (UUID):"
128 | msgstr "或者直到这些磁盘准备好(UUID):"
129 |
130 | msgid "Samba expert"
131 | msgstr "Samba高级设置"
132 |
133 | msgid "Allow legacy protocols"
134 | msgstr "允许旧协议"
135 |
136 | msgid "Allow old client, don't use this option for secure environments!"
137 | msgstr "允许老客户端连接(例如一些电视盒或手机),可能有安全风险"
138 |
139 | msgid "Sandbox"
140 | msgstr "沙箱"
141 |
142 | msgid "Simple sandbox for OpenWRT"
143 | msgstr "一个简易沙箱"
144 |
145 | msgid "This action will reboot device"
146 | msgstr "此操作将重启设备"
147 |
148 | msgid "Commit"
149 | msgstr "提交"
150 |
151 | msgid "Reset"
152 | msgstr "重置"
153 |
154 | msgid "cpufreq/sb_info"
155 | msgstr "cpufreq/sb_info.zh-cn"
156 |
157 | msgid "cpufreq/sb_guide"
158 | msgstr "cpufreq/sb_guide.zh-cn"
159 |
160 | msgid "Network"
161 | msgstr "网络"
162 |
163 | msgid "Hardware Acceleration"
164 | msgstr "硬件加速"
165 |
166 | msgid "Enable PPPoE Acceleration"
167 | msgstr "启用PPPoE加速"
168 |
169 | msgid "Improve PPPoE TX performace, only support built-in NICs"
170 | msgstr "提升PPPoE发送(TX)性能,只支持内置网卡"
171 |
172 | msgid "Exit Sandbox"
173 | msgstr "退出沙箱"
174 |
175 | msgid "Enable WAN Port Acceleration"
176 | msgstr "启用WAN口加速"
177 |
178 | msgid "Improve built-in WAN port (eth0) TX performace"
179 | msgstr "提升WAN口(eth0)发送(TX)性能"
180 |
181 | msgid "Drivers"
182 | msgstr "驱动"
183 |
184 | msgid "Drivers Settings"
185 | msgstr "驱动设置"
186 |
187 | msgid "Realtek r8125 driver"
188 | msgstr "Realtek r8125 驱动"
189 |
190 | msgid "Realtek r8168 driver"
191 | msgstr "Realtek r8168 驱动"
192 |
193 | msgid "Backported Intel GPU driver (i915-oot)"
194 | msgstr "移植 Intel GPU 驱动 (i915-oot)"
195 |
196 | msgid "Enable additional drivers"
197 | msgstr "启用额外的驱动"
198 |
199 | msgid "Configure device drivers, kernel modules, etc. Changes here will take effect on next boot"
200 | msgstr "配置设备驱动程序,内核模块等。这里的变更将在下次启动时生效"
201 |
202 | msgid "Please do not choose a driver you do not understand. Choosing the wrong driver may cause the system to fail to start"
203 | msgstr "请勿选择不了解的驱动程序,选择错误可能导致系统无法启动"
204 |
205 | msgid "Kernel Cmdline"
206 | msgstr "内核启动参数"
207 |
208 | msgid "Current Cmdline"
209 | msgstr "当前内核启动参数"
210 |
211 | msgid "This page configures Linux kernel boot parameters. After saving and applying, the GRUB configuration file of the boot partition will be modified. The parameters will take effect after restarting the system (the boot partition is not within the scope of sandbox protection, please be aware)"
212 | msgstr "此页面可配置 Linux 内核启动参数。保存并应用以后将修改 boot 分区的 GRUB 配置文件,重启系统以后参数生效(boot分区不在沙箱保护范围,请知悉)"
213 |
214 | msgid "Supports PCI device passthrough for virtual machines (KVM/QEMU)"
215 | msgstr "用于支持虚拟机(KVM/QEMU)的 PCI 设备直通"
216 |
217 | msgid "Parameters"
218 | msgstr "参数"
219 |
220 | msgid "Default"
221 | msgstr "默认"
222 |
223 | msgid "Default or empty will be automatically filled in according to the current platform"
224 | msgstr "默认或者空将自动按当前平台填写"
225 |
226 | msgid "Custom Parameters"
227 | msgstr "自定义内核参数"
228 |
229 | msgid "Danger! If you do not understand the kernel boot parameters, do not modify them to avoid being unable to start or damaging the hardware"
230 | msgstr "前方危险!如果不了解内核启动参数,请勿修改,以免无法启动或损坏硬件"
231 |
--------------------------------------------------------------------------------
/luci-app-mergerfs/htdocs/luci-static/resources/view/mergerfs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | 'require view';
3 | 'require fs';
4 | 'require ui';
5 | 'require uci';
6 | 'require rpc';
7 | 'require form';
8 |
9 | var callMountPoints = function(){
10 | return (rpc.declare({
11 | object: 'luci',
12 | method: 'getMountPoints',
13 | expect: { result: [] }
14 | }))().then(function(mounts) {
15 | // Filter out mounts that are not managed by mergerfs
16 | return (mounts || []).filter(function(mount) {
17 | return mount.device && mount.device.startsWith('mergerfs:/');
18 | });
19 | });
20 | };
21 |
22 | return view.extend({
23 |
24 | handleUmount: function(m, mounts, i, ev) {
25 | return fs.exec('/bin/umount', [mounts[i].mount])
26 | .then(function(res){
27 | if (res.code === 0)
28 | mounts.splice(i, 1);
29 | else
30 | throw new Error(res.stderr || res.message || _('Failed to unmount'));
31 | })
32 | .then(L.bind(m.render, m))
33 | .catch(function(e) { ui.addNotification(null, E('p', e.message)) });
34 | },
35 |
36 | handleReload: function(m, mounts, ev) {
37 | return fs.exec('/etc/init.d/mergerfs', ['reload'])
38 | .then(()=>
39 | new Promise(function(resolve) {
40 | setTimeout(resolve, 200);
41 | })
42 | )
43 | .then(callMountPoints)
44 | .then(function(newMounts) {
45 | if (newMounts && newMounts.length > 0) {
46 | mounts.splice(0, mounts.length, ...newMounts);
47 | } else {
48 | mounts.length = 0; // Clear the mounts if no new ones found
49 | }
50 | })
51 | .then(L.bind(m.render, m))
52 | .catch(function(e) { ui.addNotification(null, E('p', e.message)) });
53 | },
54 |
55 | load: function() {
56 | return Promise.all([
57 | callMountPoints(),
58 | ]);
59 | },
60 |
61 | render: function(data) {
62 | var m, s, o;
63 | m = new form.Map('mergerfs', _('MergerFS Pool'), _('MergerFS is a union filesystem, which allows you to pool multiple directories into a single mount point.
This is useful for combining storage space and files from multiple devices or directories into one accessible location.
New files can be distributed across the pooled directories based on various policies, such as most free space or first found.
More information can be found at GitHub.'));
64 |
65 | var mounts = data[0]||[];
66 |
67 | // Mount status table
68 | s = m.section(form.GridSection, '_mtab');
69 |
70 | s.render = L.bind(function(view, section_id) {
71 | var desc = E('div', { 'class': 'cbi-section-descr' },
72 | _('If mounting fails, search "mergerfs" in the system log for more information.')
73 | );
74 | var reload = E('div', { 'class': 'cbi-section-node' }, [
75 | E('button', {
76 | 'class': 'btn cbi-button-reload',
77 | 'click': ui.createHandlerFn(view, 'handleReload', m, mounts),
78 | }, [ _('Mount Configured MergerFS') ])
79 | ]);
80 | var table = E('table', { 'class': 'table cbi-section-table' }, [
81 | E('tr', { 'class': 'tr table-titles' }, [
82 | E('th', { 'class': 'th' }, _('Mount Point')),
83 | E('th', { 'class': 'th center' }, _('Available')),
84 | E('th', { 'class': 'th center' }, _('Used')),
85 | E('th', { 'class': 'th' }, _('Unmount'))
86 | ])
87 | ]);
88 |
89 | var rows = [];
90 |
91 | for (var i = 0; i < mounts.length; i++) {
92 | var used = mounts[i].size - mounts[i].free,
93 | umount = true;
94 |
95 | if (/^\/(overlay|rom|tmp(?:\/.+)?|dev(?:\/.+)?|)$/.test(mounts[i].mount))
96 | umount = false;
97 |
98 | rows.push([
99 | mounts[i].mount,
100 | '%1024.2mB / %1024.2mB'.format(mounts[i].avail, mounts[i].size),
101 | '%.2f%% (%1024.2mB)'.format(100 / mounts[i].size * used, used),
102 | umount ? E('button', {
103 | 'class': 'btn cbi-button-remove',
104 | 'click': ui.createHandlerFn(view, 'handleUmount', m, mounts, i),
105 | 'disabled': this.map.readonly || null
106 | }, [ _('Unmount') ]) : '-'
107 | ]);
108 | }
109 |
110 | cbi_update_table(table, rows, E('em', _('No mounted MergerFS found')));
111 |
112 | return E('div', { 'class': 'cbi-section cbi-tblsection' }, [ E('h3', _('Mounted MergerFS')), desc, reload, table ]);
113 | }, s, this);
114 |
115 | // 基本信息分区
116 | s = m.section(form.GridSection, 'pool', _('Pool Settings'));
117 | s.anonymous = true;
118 | s.addremove = true;
119 |
120 | o = s.option(form.Flag, 'enabled', _('Enabled'));
121 | o.rmempty = false;
122 | o.default = true;
123 | o.editable = true;
124 |
125 | // type: textInput, name: mountpoint
126 | o = s.option(form.Value, 'mountpoint', _('Mount Point'), _('Mount to this path'));
127 | o.datatype = 'string';
128 | o.placeholder = '/mnt/mergerfs';
129 | o.rmempty = false;
130 | // o.editable = true;
131 | o.validate = function(section_id, value) {
132 | value = value ? value.trim() : value;
133 | if (!value || !value.startsWith('/') || value === '/') {
134 | return _('Mount Point is required, must start with "/" and cannot be root "/"');
135 | }
136 | return true;
137 | };
138 | o.cfgvalue = function(section_id) {
139 | var v = uci.get('mergerfs', section_id, 'mountpoint');
140 | return v ? v.trim() : v;
141 | };
142 | o.write = function(section_id, formvalue) {
143 | return uci.set('mergerfs', section_id, 'mountpoint', formvalue ? formvalue.trim() : formvalue);
144 | };
145 |
146 | var clean_paths = function(val) {
147 | if (!val || typeof val !== 'string') return val;
148 | return val.split('\n').map(function(line) {
149 | line = line.trim();
150 | if (line.startsWith('#')) return line;
151 | if (line !== '/' && line.endsWith('/')) {
152 | return line.slice(0, -1);
153 | }
154 | return line;
155 | }).join('\n');
156 | };
157 |
158 | // type: textarea, name: paths
159 | o = s.option(form.TextValue, 'paths', _('Paths'), _("List of paths to merge, one per line. Line starting with '#' will be treated as a comment.
All paths must existed before mounting or the mounting will fail."));
160 | o.datatype = 'string';
161 | o.modalonly = true;
162 | o.rows = 5;
163 | o.placeholder = _('Put each folder on a new line.');
164 | o.validate = function(section_id, value) {
165 | var paths = clean_paths(value).split('\n');
166 | if (!paths.every(function(line) { return line.length === 0 || line.startsWith('/') || line.startsWith('#'); })) {
167 | return _("Each line must be a path starting with a '/' or be a comment starting with '#'.");
168 | }
169 | if (!paths.some(function(line) { return line && line.startsWith('/'); })) {
170 | return _('You must provide at least one valid path (not a comment or empty line).');
171 | }
172 | return true;
173 | };
174 | o.cfgvalue = function(section_id) {
175 | var v = uci.get('mergerfs', section_id, 'paths');
176 | return clean_paths(v);
177 | };
178 | o.write = function(section_id, formvalue) {
179 | return uci.set('mergerfs', section_id, 'paths', clean_paths(formvalue));
180 | };
181 |
182 | // type: select, name: createpolicy
183 | o = s.option(form.ListValue, 'createpolicy', _('Create policy'), _('Policy for creating new files'));
184 | o.editable = true;
185 | o.value('epall', _('Existing path - all'));
186 | o.value('epff', _('Existing path - first found'));
187 | o.value('eplfs', _('Existing path - least free space'));
188 | o.value('eplus', _('Existing path - least used space'));
189 | o.value('epmfs', _('Existing path - most free space'));
190 | o.value('eppfrd', _('Existing path - percentage free random distribution'));
191 | o.value('eprand', _('Existing path - random'));
192 | o.value('erofs', _('Read-only'));
193 | o.value('ff', _('First found'));
194 | o.value('lfs', _('Least free space'));
195 | o.value('lus', _('Least used space'));
196 | o.value('mfs', _('Most free space'));
197 | o.value('msplfs', _('Most shared path - least free space'));
198 | o.value('msplus', _('Most shared path - least used space'));
199 | o.value('mspmfs', _('Most shared path - most free space'));
200 | o.value('msppfrd', _('Most shared path - percentage free random distribution'));
201 | o.value('newest', _('Newest file'));
202 | o.value('pfrd', _('Percentage free random distribution'));
203 | o.value('rand', _('Random'));
204 | o.default = 'epmfs';
205 |
206 | var parse_minfreespace = function(value) {
207 | if (!value || typeof value !== 'string') return '';
208 | // 去除所有空格
209 | value = value.replace(/\s+/g, '');
210 | // 转大写
211 | value = value.toUpperCase();
212 | // 去除尾部B
213 | if (value.endsWith('B')) value = value.slice(0, -1);
214 | if (value == '') return value;
215 | // 保证有数字+单位,且单位为K/M/G之一
216 | var m = value.match(/^(\d+)([KMG])$/);
217 | if (m) {
218 | return m[1] + m[2];
219 | }
220 | // 如果用户只输入了数字,默认加G
221 | m = value.match(/^(\d+)$/);
222 | if (m) {
223 | return m[1] + 'G';
224 | }
225 | // 否则返回原值
226 | return value;
227 | };
228 |
229 | // type: numberInput, name: minfreespace
230 | o = s.option(form.Value, 'minfreespace', _('Minimum free space'));
231 | o.placeholder = '4G';
232 | o.editable = true;
233 | o.validate = function(section_id, value) {
234 | var parsed = parse_minfreespace(value);
235 | if (parsed == '' || /^\d+[KMG]$/.test(parsed)) {
236 | return true;
237 | }
238 | return _('Please enter a value like 4G, 500M, 100K');
239 | };
240 | o.cfgvalue = function(section_id) {
241 | var v = uci.get('mergerfs', section_id, 'minfreespace');
242 | return parse_minfreespace(v);
243 | };
244 | o.write = function(section_id, formvalue) {
245 | return uci.set('mergerfs', section_id, 'minfreespace', parse_minfreespace(formvalue));
246 | };
247 |
248 | // type: textInput, name: options
249 | o = s.option(form.Value, 'options', _('Options'));
250 | o.modalonly = true;
251 | o.placeholder = 'defaults,cache.files=off';
252 | //o.default = 'defaults,cache.files=off';
253 |
254 | return m.render();
255 | }
256 | });
--------------------------------------------------------------------------------