update 2024-11-09 10:40:00

This commit is contained in:
kenzok8 2024-11-09 10:40:00 +08:00
parent 31f7450503
commit 3d705c39a0
14 changed files with 453 additions and 0 deletions

View File

@ -0,0 +1,18 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.1.2-20240822
PKG_RELEASE:=
LUCI_TITLE:=LuCI support for istoredup
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd
define Package/luci-app-istoredup/conffiles
/etc/config/istoredup
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,9 @@
module("luci.controller.istoredup", package.seeall)
function index()
entry({"admin", "services", "istoredup"}, alias("admin", "services", "istoredup", "config"), _("iStoreDup"), 30).dependent = true
entry({"admin", "services", "istoredup", "config"}, cbi("istoredup/config"), _("Config"), 10).leaf = true
entry({"admin", "services", "istoredup", "tool"}, form("istoredup/tool"), _("Tool"), 30).leaf = true
entry({"admin", "services", "istoredup", "console"}, form("istoredup/console"), _("Console"), 50).leaf = true
end

View File

@ -0,0 +1,31 @@
--[[
LuCI - Lua Configuration Interface
]]--
local taskd = require "luci.model.tasks"
local istoredup_model = require "luci.model.istoredup"
local m, s, o
m = taskd.docker_map("istoredup", "istoredup", "/usr/libexec/istorec/istoredup.sh",
translate("iStoreDup"),
translate("A duplica of iStoreOS.")
.. translate("Official website:") .. ' <a href=\"https://www.istoreos.com/\" target=\"_blank\">https://www.istoreos.com/</a>')
s = m:section(SimpleSection, translate("Service Status"), translate("iStoreDup status:"))
s:append(Template("istoredup/status"))
s = m:section(TypedSection, "istoredup", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
s.addremove=false
s.anonymous=true
o = s:option(Value, "image_name", translate("Image").."<b>*</b>")
o.rmempty = false
o.datatype = "string"
o:value("linkease/istoreduprk35xx:latest", "linkease/istoreduprk35xx:latest")
o.default = "linkease/istoreduprk35xx:latest"
o = s:option(Value, "time_zone", translate("Timezone"))
o.datatype = "string"
o:value("Asia/Shanghai", "Asia/Shanghai")
return m

View File

@ -0,0 +1,116 @@
--[[
LuCI - Lua Configuration Interface
]]--
require "luci.util"
local docker = require "luci.model.docker"
local dk = docker.new()
local container_name = "istoredup"
local m, s, o
local images, networks, container_info, res
res = dk.containers:inspect({name = container_name})
if res.code < 300 then
container_info = res.body
else
return
end
local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil
local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil
if cmd_docker and cmd_ttyd and container_info.State.Status == "running" then
local cmd = "/bin/bash"
local uid
m=SimpleForm("Console", "", translate("Only works in LAN"))
m.submit = false
m.reset = false
s = m:section(SimpleSection)
o = s:option(Value, "command", translate("Command"))
o:value("/bin/sh", "/bin/sh")
o:value("/bin/ash", "/bin/ash")
o:value("/bin/bash", "/bin/bash")
o.default = "/bin/bash"
o.forcewrite = true
o.write = function(self, section, value)
cmd = value
end
o = s:option(Value, "uid", translate("UID"))
o.forcewrite = true
o.write = function(self, section, value)
uid = value
end
o = s:option(Button, "connect")
o.render = function(self, section, scope)
self.inputstyle = "add"
self.title = " "
self.inputtitle = translate("Connect")
Button.render(self, section, scope)
end
o.write = function(self, section)
local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil
local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil
if not cmd_docker or not cmd_ttyd or cmd_docker:match("^%s+$") or cmd_ttyd:match("^%s+$")then
return
end
local pid = luci.util.trim(luci.util.exec("netstat -lnpt | grep :7682 | grep ttyd | tr -s ' ' | cut -d ' ' -f7 | cut -d'/' -f1"))
if pid and pid ~= "" then
luci.util.exec("kill -9 " .. pid)
end
local hosts
local uci = require "luci.model.uci".cursor()
local remote = uci:get_bool("dockerd", "globals", "remote_endpoint") or false
local host = nil
local port = nil
local socket = nil
if remote then
host = uci:get("dockerd", "globals", "remote_host") or nil
port = uci:get("dockerd", "globals", "remote_port") or nil
else
socket = uci:get("dockerd", "globals", "socket_path") or "/var/run/docker.sock"
end
if remote and host and port then
hosts = host .. ':'.. port
elseif socket then
hosts = socket
else
return
end
if uid and uid ~= "" then
uid = "-u " .. uid
else
uid = ""
end
local start_cmd = string.format('%s -d 2 --once -p 7682 %s -H "unix://%s" exec -it %s %s %s&', cmd_ttyd, cmd_docker, hosts, uid, container_name, cmd)
os.execute(start_cmd)
m.children[#m.children] = nil
s = m:section(SimpleSection)
o = s:option(DummyValue, "console")
o.container_id = container_id
o.template = container_name .. "/console"
end
else
m=SimpleForm("Console", "", translate("iStoreDup is not running"))
m.submit = false
m.reset = false
s = m:section(SimpleSection)
end
return m

View File

@ -0,0 +1,41 @@
--[[
LuCI - Lua Configuration Interface
]]--
local http = require 'luci.http'
m=SimpleForm("Tools")
m.submit = false
m.reset = false
s = m:section(SimpleSection)
o = s:option(Value, "action", translate("Action").."<b>*</b>")
o.rmempty = false
o.datatype = "string"
o:value("show-ip", "show-ip")
o.default = "show-ip"
local t=Template("istoredup/tool")
m:append(t)
local btn_do = s:option(Button, "_do")
btn_do.render = function(self, section, scope)
self.inputstyle = "add"
self.title = " "
self.inputtitle = translate("Execute")
Button.render(self, section, scope)
end
btn_do.write = function(self, section, value)
local action = m:get(section, "action")
if action == "show-ip" then
local cmd = string.format("/usr/libexec/istorec/istoredup.sh %s", action)
cmd = "/etc/init.d/tasks task_add istoredup " .. luci.util.shellquote(cmd) .. " >/dev/null 2>&1"
os.execute(cmd)
t.show_log_taskid = "istoredup"
end
end
return m

View File

@ -0,0 +1,55 @@
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local emby = {}
emby.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
emby.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
emby.find_paths = function(blocks, home_dirs, path_name)
local default_path = ''
local configs = {}
default_path = home_dirs[path_name] .. "/iStoreDup"
if #blocks == 0 then
table.insert(configs, default_path)
else
for _, val in pairs(blocks) do
table.insert(configs, val .. "/" .. path_name .. "/iStoreDup")
end
local without_conf_dir = "/root/" .. path_name .. "/iStoreDup"
if default_path == without_conf_dir then
default_path = configs[1]
end
end
return configs, default_path
end
return emby

View File

@ -0,0 +1,6 @@
<div class="cbi-map">
<iframe id="terminal" style="width: 100%; min-height: 600px; border: none; border-radius: 3px;"></iframe>
</div>
<script type="text/javascript">
document.getElementById("terminal").src = "http://" + window.location.hostname + ":7682";
</script>

View File

@ -0,0 +1,31 @@
<%
local util = require "luci.util"
local container_status = util.trim(util.exec("/usr/libexec/istorec/istoredup.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"><%:iStoreDup is running%></button>
<% else %>
<button class="cbi-button cbi-button-negative" disabled="true"><%:iStoreDup is not running%></button>
<% end %>
</div>
</div>
<%
if container_running then
local port=util.trim(util.exec("/usr/libexec/istorec/istoredup.sh port"))
if port == "" then
port="error"
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 the iStoreDup%>" onclick="window.open('http://<%=port%>/', '_blank')">
</div>
</div>
<% end %>

View File

@ -0,0 +1,11 @@
<%+tasks/embed%>
<script>
window.addEventListener("load", function(){
const taskd = window.taskd;
<% if self.show_log_taskid then -%>
taskd.show_log("<%=self.show_log_taskid%>");
<%- end %>
});
</script>

View File

@ -0,0 +1,48 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Official website:"
msgstr "官方网站:"
msgid "A duplica of iStoreOS."
msgstr "iStoreOS 的分身,可以把风险高的软件安装到分身里面,出问题不影响到主系统。"
msgid "Service Status"
msgstr "服务状态"
msgid "iStoreDup status:"
msgstr "iStoreDup 的状态信息如下:"
msgid "Setup"
msgstr "安装配置"
msgid "The following parameters will only take effect during installation or upgrade:"
msgstr "以下参数只在安装或者升级时才会生效:"
msgid "Status"
msgstr "状态"
msgid "iStoreDup is running"
msgstr "iStoreDup 运行中"
msgid "iStoreDup is not running"
msgstr "iStoreDup 未运行"
msgid "Open the iStoreDup"
msgstr "打开 iStoreDup"
msgid "Tool"
msgstr "操作"
msgid "Console"
msgstr "控制台"
msgid "Only works in LAN"
msgstr "只在内网环境下工作。"
msgid "Execute"
msgstr "执行"
msgid "Timezone"
msgstr "时区"

View File

@ -0,0 +1 @@
zh-cn

View File

@ -0,0 +1,4 @@
config istoredup
option 'config_path' ''
option 'image_name' 'istoredup/home-assistant:latest'
option 'time_zone' ''

View File

@ -0,0 +1,71 @@
#!/bin/sh
ACTION=${1}
shift 1
do_install() {
local IMAGE_NAME=`uci get istoredup.@istoredup[0].image_name 2>/dev/null`
echo "docker pull ${IMAGE_NAME}"
docker pull ${IMAGE_NAME}
docker rm -f istoredup
local hasvlan=`docker network inspect dsm-net -f '{{.Name}}' 2>/dev/null`
if [ ! "$hasvlan" = "dsm-net" ]; then
docker network create -o com.docker.network.bridge.name=dsm-br --driver=bridge dsm-net
fi
local mask=`ubus call network.interface.lan status | jsonfilter -e '@["ipv4-address"][0].mask'`
local cmd="docker run --restart=unless-stopped -d \
-h iStoreDuplica \
-v /var/run/vmease:/var/run/vmease \
--privileged \
--net=dsm-net \
--sysctl net.netfilter.nf_conntrack_acct=1 \
--sysctl net.ipv4.conf.all.forwarding=1 \
--dns=172.17.0.1 "
cmd="$cmd -v /mnt:/mnt"
mountpoint -q /mnt && cmd="$cmd:rslave"
cmd="$cmd --stop-timeout 120 --name istoredup \"$IMAGE_NAME\""
echo "$cmd"
eval "$cmd"
}
usage() {
echo "usage: $0 sub-command"
echo "where sub-command is one of:"
echo " install Install the istoredup"
echo " upgrade Upgrade the istoredup"
echo " rm/start/stop/restart Remove/Start/Stop/Restart the istoredup"
echo " status iStoreDup status"
echo " port iStoreDup port"
}
case ${ACTION} in
"install")
do_install
;;
"upgrade")
do_install
;;
"rm")
docker rm -f istoredup
;;
"start" | "stop" | "restart")
docker ${ACTION} istoredup
;;
"status")
docker ps --all -f 'name=^/istoredup$' --format '{{.State}}'
;;
"port")
docker exec istoredup ip -f inet addr show br-lan|sed -En -e 's/.*inet ([0-9.]+).*/\1/p'
;;
"show-ip")
docker exec istoredup ip -f inet addr show br-lan|sed -En -e 's/.*inet ([0-9.]+).*/\1/p'
;;
*)
usage
exit 1
;;
esac

View File

@ -0,0 +1,11 @@
{
"luci-app-istoredup": {
"description": "Grant UCI access for luci-app-istoredup",
"read": {
"uci": [ "istoredup" ]
},
"write": {
"uci": [ "istoredup" ]
}
}
}