🌴 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

+20
View File
@@ -0,0 +1,20 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.1.1-20240822
PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for ubuntu
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+docker +dockerd +luci-lib-iform +luci-lib-taskd
LUCI_EXTRA_DEPENDS:=luci-lib-iform (>=1.1)
define Package/luci-app-ubuntu/conffiles
/etc/config/ubuntu
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+242
View File
@@ -0,0 +1,242 @@
local util = require "luci.util"
local http = require "luci.http"
local docker = require "luci.model.docker"
local iform = require "luci.iform"
module("luci.controller.ubuntu", package.seeall)
function index()
entry({"admin", "services", "ubuntu"}, call("redirect_index"), _("Ubuntu"), 30).dependent = true
entry({"admin", "services", "ubuntu", "pages"}, call("ubuntu_index")).leaf = true
entry({"admin", "services", "ubuntu", "form"}, call("ubuntu_form"))
entry({"admin", "services", "ubuntu", "submit"}, call("ubuntu_submit"))
end
local appname = "ubuntu"
local page_index = {"admin", "services", "ubuntu", "pages"}
function redirect_index()
http.redirect(luci.dispatcher.build_url(unpack(page_index)))
end
function ubuntu_index()
luci.template.render("ubuntu/main", {prefix=luci.dispatcher.build_url(unpack(page_index))})
end
function ubuntu_form()
local error = ""
local scope = ""
local success = 0
local data = get_data()
local result = {
data = data,
schema = get_schema(data)
}
local response = {
error = error,
scope = scope,
success = success,
result = result,
}
http.prepare_content("application/json")
http.write_json(response)
end
function get_schema(data)
local actions
if data.container_install then
actions = {
{
name = "restart",
text = "重启",
type = "apply",
},
{
name = "upgrade",
text = "更新",
type = "apply",
},
{
name = "remove",
text = "删除",
type = "apply",
},
}
else
actions = {
{
name = "install",
text = "安装",
type = "apply",
},
}
end
local schema = {
actions = actions,
containers = get_containers(data),
description = "带 Web 远程桌面的 Docker 高性能版 Ubuntu。默认<用户名:kasm_user 密码:password> 访问官网 <a href=\"https://www.kasmweb.com/\" target=\"_blank\">https://www.kasmweb.com/</a>",
title = "Ubuntu"
}
return schema
end
function get_containers(data)
local containers = {
status_container(data),
main_container(data)
}
return containers
end
function status_container(data)
local status_value
if data.container_install then
status_value = "Ubuntu 运行中"
else
status_value = "Ubuntu 未运行"
end
local status_c1 = {
labels = {
{
key = "状态:",
value = status_value
},
{
key = "访问:",
value = ""
-- value = "'<a href=\"https://' + location.host + ':6901\" target=\"_blank\">Ubuntu 桌面</a>'"
}
},
description = "访问链接是一个自签名的 https,需要浏览器同意才能访问!",
title = "服务状态"
}
return status_c1
end
function main_container(data)
local main_c2 = {
properties = {
{
name = "port",
required = true,
title = "端口",
type = "string"
},
{
name = "password",
required = true,
title = "密码",
type = "string"
},
{
name = "version",
required = true,
title = "安装版本",
type = "string",
enum = {"standard", "full"},
enumNames = {"Standard Version", "Full Version"}
},
},
description = "请选择合适的版本进行安装:",
title = "服务操作"
}
return main_c2
end
function get_data()
local uci = require "luci.model.uci".cursor()
local docker_path = util.exec("which docker")
local docker_install = (string.len(docker_path) > 0)
-- docker ps -aqf
local container_id = util.trim(util.exec("docker ps -qf 'name="..appname.."'"))
local container_install = (string.len(container_id) > 0)
local port = tonumber(uci:get_first(appname, appname, "port", "6901"))
local data = {
port = port,
user_name = "kasm_user",
password = uci:get_first(appname, appname, "password", ""),
version = uci:get_first(appname, appname, "version", "standard"),
container_install = container_install
}
return data
end
function ubuntu_submit()
local error = ""
local scope = ""
local success = 0
local result
local jsonc = require "luci.jsonc"
local json_parse = jsonc.parse
local content = http.content()
local req = json_parse(content)
if req["$apply"] == "upgrade" then
result = install_upgrade_ubuntu(req)
elseif req["$apply"] == "install" then
result = install_upgrade_ubuntu(req)
elseif req["$apply"] == "restart" then
result = restart_ubuntu(req)
else
result = delete_ubuntu()
end
http.prepare_content("application/json")
local resp = {
error = error,
scope = scope,
success = success,
result = result,
}
http.write_json(resp)
end
function install_upgrade_ubuntu(req)
local password = req["password"]
local port = req["port"]
local version = req["version"]
-- save config
local uci = require "luci.model.uci".cursor()
uci:tset(appname, "@"..appname.."[0]", {
password = password or "password",
port = port or "6901",
version = version or "standard",
})
uci:save(appname)
uci:commit(appname)
local exec_cmd = string.format("/usr/libexec/istorec/ubuntu.sh %s", req["$apply"])
exec_cmd = "/etc/init.d/tasks task_add ubuntu " .. luci.util.shellquote(exec_cmd)
os.execute(exec_cmd .. " >/dev/null 2>&1")
local result = {
async = true,
async_state = appname
}
return result
end
function delete_ubuntu()
local log = iform.exec_to_log("docker rm -f ubuntu")
local result = {
async = false,
log = log
}
return result
end
function restart_ubuntu()
local log = iform.exec_to_log("docker restart ubuntu")
local result = {
async = false,
log = log
}
return result
end
@@ -0,0 +1,35 @@
<%+header%>
<%+tasks/embed%>
<script>
(function(){
})();
</script>
<div id="app">
</div>
<script>
window.IstoreosFormConfig = {
getApi:"/cgi-bin/luci/admin/services/ubuntu/form/",
logApi:"/cgi-bin/luci/admin/services/ubuntu/log",
submitApi:"/cgi-bin/luci/admin/services/ubuntu/submit",
getHook:function(resp){
var c1 = resp.result.schema.containers[0];
if (resp.result.data.container_install) {
c1.labels[1].value = '<a href="https://'+location.host+':'+resp.result.data.port+'" target="_blank">Ubuntu 桌面链接</a>';
} else {
c1.labels[1].value = "安装并运行之后,才能用网页访问";
}
// console.log("resp=", data);
return resp;
},
submitHook:function(params){
return params;
}
}
</script>
<script type="module" crossorigin src="/luci-static/iform/1.1/index.js?v=<%=math.random(1,100000)%>"></script>
<link rel="stylesheet" href="/luci-static/iform/1.1/style.css?v=<%=math.random(1,100000)%>">
<%+footer%>
+62
View File
@@ -0,0 +1,62 @@
msgid "ubuntu"
msgstr "ubuntu"
msgid "The ubuntu service is running."
msgstr "ubuntu已启动"
msgid "The ubuntu service is not running."
msgstr "ubuntu服务未启动"
msgid "The ubuntu service is not installed."
msgstr "ubuntu服务未安装"
msgid "open ubuntu"
msgstr "打开ubuntu"
msgid "stop ubuntu"
msgstr "停止ubuntu"
msgid "run ubuntu"
msgstr "启动ubuntu"
msgid "uninstall ubuntu"
msgstr "删除ubuntu"
msgid "install ubuntu"
msgstr "安装ubuntu"
msgid "Collecting data..."
msgstr "收集数据..."
msgid "storage path"
msgstr "存储路径(建议插入U盘或硬盘,然后输入路径。例如:/mnt/sda1/ubuntu)"
msgid "Storage path could not be empty!"
msgstr "存储路径不能为空!"
msgid "Version"
msgstr "系统版本"
msgid "Port (optional)"
msgstr "端口"
msgid "Password (optional)"
msgstr "密码"
msgid "standard version"
msgstr "标准版本"
msgid "full version"
msgstr "全量版本"
msgid "UserName"
msgstr "用户名"
msgid "Password"
msgstr "密码"
msgid "LanAddress"
msgstr "内网地址"
msgid "WanAddress"
msgstr "外网地址"
+1
View File
@@ -0,0 +1 @@
zh-cn
+5
View File
@@ -0,0 +1,5 @@
config ubuntu
option 'image' 'linkease/desktop-ubuntu-standard-arm64:latest'
option 'password' 'password'
option 'port' '6901'
option 'version' 'standard'
+91
View File
@@ -0,0 +1,91 @@
#!/bin/sh
# Author Xiaobao(xiaobao@linkease.com)
ACTION=${1}
shift 1
IMAGE_NAME=''
# linkease/desktop-ubuntu-full-arm64:latest
# linkease/desktop-ubuntu-standard-arm64:latest
# linkease/desktop-ubuntu-full-amd64:latest
# linkease/desktop-ubuntu-standard-amd64:latest
get_image() {
local version=`uci get ubuntu.@ubuntu[0].version 2>/dev/null`
ARCH="arm64"
if echo `uname -m` | grep -Eqi 'x86_64'; then
ARCH='amd64'
elif echo `uname -m` | grep -Eqi 'aarch64'; then
ARCH='arm64'
else
ARCH='arm64'
fi
IMAGE_NAME=linkease/desktop-ubuntu-${version}-${ARCH}:latest
}
do_install() {
local http_port=`uci get ubuntu.@ubuntu[0].port 2>/dev/null`
local password=`uci get ubuntu.@ubuntu[0].password 2>/dev/null`
[ -z $password ] || password="password"
[ -z $http_port ] || http_port=6901
get_image
echo "docker pull ${IMAGE_NAME}"
docker pull ${IMAGE_NAME}
docker rm -f ubuntu
local cmd="docker run --restart=unless-stopped -d \
--dns=172.17.0.1 \
-u=0:0 \
--shm-size=512m \
-p ${http_port}:6901 \
-e VNC_PW=${password} \
-e VNC_USE_HTTP=0 "
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 ubuntu \"$IMAGE_NAME\""
echo "$cmd"
eval "$cmd"
}
usage() {
echo "usage: $0 sub-command"
echo "where sub-command is one of:"
echo " install Install the ubuntu"
echo " upgrade Upgrade the ubuntu"
echo " rm/start/stop/restart Remove/Start/Stop/Restart the ubuntu"
echo " status Ubuntu status"
echo " port Ubuntu port"
}
case ${ACTION} in
"install")
do_install
;;
"upgrade")
do_install
;;
"rm")
docker rm -f ubuntu
;;
"start" | "stop" | "restart")
docker ${ACTION} ubuntu
;;
"status")
docker ps --all -f 'name=^/ubuntu$' --format '{{.State}}'
;;
"port")
docker ps --all -f 'name=^/ubuntu$' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
;;
*)
usage
exit 1
;;
esac
@@ -0,0 +1,11 @@
{
"luci-app-ubuntu": {
"description": "Grant UCI access for luci-app-ubuntu",
"read": {
"uci": [ "ubuntu" ]
},
"write": {
"uci": [ "ubuntu" ]
}
}
}