🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.0.8-20250207
PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for OpenWebUI
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker
define Package/luci-app-openwebui/conffiles
/etc/config/openwebui
endef
define Package/luci-app-openwebui/prerm
#!/bin/sh
/usr/libexec/istorec/openwebui.sh stop
exit 0
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+7
View File
@@ -0,0 +1,7 @@
module("luci.controller.openwebui", package.seeall)
function index()
entry({"admin", "services", "openwebui"}, alias("admin", "services", "openwebui", "config"), _("OpenWebUI"), 30).dependent = true
entry({"admin", "services", "openwebui", "config"}, cbi("openwebui"))
end
@@ -0,0 +1,58 @@
--[[
LuCI - Lua Configuration Interface
]]--
local taskd = require "luci.model.tasks"
local docker = require "luci.docker"
local openwebui_model = require "luci.model.openwebui"
local m, s, o
m = taskd.docker_map("openwebui", "openwebui", "/usr/libexec/istorec/openwebui.sh",
translate("OpenWebUI"),
translate("Open WebUI is an extensible, self-hosted AI interface that adapts to your workflow, all while operating entirely offline.")
.. translate("Official website:") .. ' <a href=\"https://openwebui.com/\" target=\"_blank\">https://openwebui.com/</a>')
local dk = docker.new({socket_path="/var/run/docker.sock"})
local dockerd_running = dk:_ping().code == 200
local docker_info = dockerd_running and dk:info().body or {}
local docker_aspace = 0
if docker_info.DockerRootDir then
local statvfs = nixio.fs.statvfs(docker_info.DockerRootDir)
docker_aspace = statvfs and (statvfs.bavail * statvfs.bsize) or 0
end
s = m:section(SimpleSection, translate("Service Status"), translate("OpenWebUI status:"))
s:append(Template("openwebui/status"))
s = m:section(TypedSection, "main", translate("Setup"),
(docker_aspace < 2147483648 and
(translate("The free space of Docker is less than 2GB, which may cause the installation to fail.")
.. "<br>") or "") .. translate("The following parameters will only take effect during installation or upgrade:"))
s.addremove=false
s.anonymous=true
o = s:option(Value, "port", translate("Port").."<b>*</b>")
o.default = "3000"
o.datatype = "port"
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
o.rmempty = false
o.datatype = "string"
o:value("ghcr.io/open-webui/open-webui:main", "ghcr.io/open-webui/open-webui:main")
o:value("linkease/open-webui:main", "linkease/open-webui:main")
o.default = "linkease/open-webui:main"
local blocks = openwebui_model.blocks()
local home = openwebui_model.home()
o = s:option(Value, "config_path", translate("Config path").."<b>*</b>")
o.rmempty = false
o.datatype = "string"
local paths, default_path = openwebui_model.find_paths(blocks, home, "Configs")
for _, val in pairs(paths) do
o:value(val, val)
end
o.default = default_path
return m
@@ -0,0 +1,55 @@
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local openwebui = {}
openwebui.blocks = function()
local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
local vals = {}
if f then
local ret = f:read("*all")
f:close()
local obj = jsonc.parse(ret)
for _, val in pairs(obj["blockdevices"]) do
local fsize = val["fssize"]
if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
-- fsize > 1G
vals[#vals+1] = val["mountpoint"]
end
end
end
return vals
end
openwebui.home = function()
local uci = require "luci.model.uci".cursor()
local home_dirs = {}
home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
return home_dirs
end
openwebui.find_paths = function(blocks, home_dirs, path_name)
local default_path = ''
local configs = {}
default_path = home_dirs[path_name] .. "/OpenWebUI"
if #blocks == 0 then
table.insert(configs, default_path)
else
for _, val in pairs(blocks) do
table.insert(configs, val .. "/" .. path_name .. "/OpenWebUI")
end
local without_conf_dir = "/root/" .. path_name .. "/OpenWebUI"
if default_path == without_conf_dir then
default_path = configs[1]
end
end
return configs, default_path
end
return openwebui
@@ -0,0 +1,31 @@
<%
local util = require "luci.util"
local container_status = util.trim(util.exec("/usr/libexec/istorec/openwebui.sh status"))
local container_install = (string.len(container_status) > 0)
local container_running = container_status == "running"
-%>
<div class="cbi-value">
<label class="cbi-value-title"><%:Status%></label>
<div class="cbi-value-field">
<% if container_running then %>
<button class="cbi-button cbi-button-success" disabled="true"><%:OpenWebUI is running%></button>
<% else %>
<button class="cbi-button cbi-button-negative" disabled="true"><%:OpenWebUI is not running%></button>
<% end %>
</div>
</div>
<%
if container_running then
local port=util.trim(util.exec("/usr/libexec/istorec/openwebui.sh port"))
if port == "" then
port="3000"
end
-%>
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title">&nbsp;</label>
<div class="cbi-value-field">
<input type="button" class="btn cbi-button cbi-button-apply" name="start" value="<%:Open OpenWebUI%>" onclick="window.open('http://'+location.hostname+':<%=port%>/', '_blank')">
</div>
</div>
<% end %>
+44
View File
@@ -0,0 +1,44 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Official website:"
msgstr "官方网站:"
msgid "Open WebUI is an extensible, self-hosted AI interface that adapts to your workflow, all while operating entirely offline."
msgstr "Open WebUI 是一款可扩展、自托管的 AI 界面,能够无缝适配您的工作流程,且所有操作均可完全离线运行。"
msgid "Config path"
msgstr "配置文件路径"
msgid "Port"
msgstr "端口"
msgid "Service Status"
msgstr "服务状态"
msgid "OpenWebUI status:"
msgstr "OpenWebUI 的状态信息如下:"
msgid "Setup"
msgstr "安装配置"
msgid "The following parameters will only take effect during installation or upgrade:"
msgstr "以下参数只在安装或者升级时才会生效:"
msgid "Status"
msgstr "状态"
msgid "OpenWebUI is running"
msgstr "OpenWebUI 运行中"
msgid "OpenWebUI is not running"
msgstr "OpenWebUI 未运行"
msgid "Open OpenWebUI"
msgstr "打开 OpenWebUI"
msgid "The free space of Docker is less than 2GB, which may cause the installation to fail."
msgstr "Docker 可用空间已不足2GB,可能导致安装失败。"
msgid "Please make sure there has enough space"
msgstr "请确保有足够空间"
+1
View File
@@ -0,0 +1 @@
zh-cn
@@ -0,0 +1,2 @@
config main
option 'port' '3000'
+86
View File
@@ -0,0 +1,86 @@
#!/bin/sh
# Author Xiaobao(xiaobao@linkease.com)
ACTION=${1}
shift 1
do_install() {
local port=`uci get openwebui.@main[0].port 2>/dev/null`
local image_name=`uci get openwebui.@main[0].image_name 2>/dev/null`
local config=`uci get openwebui.@main[0].config_path 2>/dev/null`
if [ -z "$config" ]; then
echo "config path is empty!"
exit 1
fi
[ -z "$port" ] && port=10086
mkdir -p $config
[ -z "$image_name" ] && image_name="backplane/open-webui:main"
echo "docker pull ${image_name}"
docker pull ${image_name}
RET=$?
if [ ! "$RET" = "0" ]; then
echo "download failed"
exit 1
fi
docker rm -f openwebui
local cmd="docker run --restart=unless-stopped -d -h OpenWebUIServer \
-e OPENAI_API_KEY=your_secret_key \
-p $port:8080 \
-v \"$config:/app/backend/data\" "
cmd="$cmd\
--dns=172.17.0.1 \
--dns=223.5.5.5 "
local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`"
[ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
cmd="$cmd -v /mnt:/mnt"
mountpoint -q /mnt && cmd="$cmd:rslave"
cmd="$cmd --name openwebui \"$image_name\""
echo "$cmd"
eval "$cmd"
echo "Initial..."
sleep 10
echo "Done"
}
usage() {
echo "usage: $0 sub-command"
echo "where sub-command is one of:"
echo " install Install the openwebui"
echo " upgrade Upgrade the openwebui"
echo " rm/start/stop/restart Remove/Start/Stop/Restart the openwebui"
echo " status OpenWebUI status"
echo " port OpenWebUI port"
}
case ${ACTION} in
"install")
do_install
;;
"upgrade")
do_install
;;
"rm")
docker rm -f openwebui
;;
"start" | "stop" | "restart")
docker ${ACTION} openwebui
;;
"status")
docker ps --all -f 'name=^/openwebui$' --format '{{.State}}'
;;
"port")
docker ps --all -f 'name=^/htreader$' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*->9060/tcp' | sed 's/0.0.0.0:\([0-9]*\)->.*/\1/'
;;
*)
usage
exit 1
;;
esac
@@ -0,0 +1,11 @@
{
"luci-app-openwebui": {
"description": "Grant UCI access for luci-app-openwebui",
"read": {
"uci": [ "openwebui" ]
},
"write": {
"uci": [ "openwebui" ]
}
}
}