add luci-app-ubuntu

This commit is contained in:
YGAS 2021-12-24 13:10:32 +08:00
parent b22f3e9664
commit 8441e48eea
8 changed files with 389 additions and 0 deletions

View File

@ -0,0 +1,19 @@
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.0.1
PKG_RELEASE:=2021224
LUCI_TITLE:=LuCI support for ubuntu
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+docker +luci-app-dockerman
define Package/luci-app-ubuntu/conffiles
/etc/config/ubuntu
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,143 @@
module("luci.controller.ubuntu", package.seeall)
function index()
entry({'admin', 'services', 'ubuntu'}, alias('admin', 'services', 'ubuntu', 'client'), _('ubuntu'), 10)
entry({"admin", "services", "ubuntu",'client'}, cbi("ubuntu/status"), nil).leaf = true
entry({"admin", "services", "ubuntu","status"}, call("get_container_status"))
entry({"admin", "services", "ubuntu","stop"}, post("stop_container"))
entry({"admin", "services", "ubuntu","start"}, post("start_container"))
entry({"admin", "services", "ubuntu","install"}, post("install_container"))
entry({"admin", "services", "ubuntu","uninstall"}, post("uninstall_container"))
end
local sys = require "luci.sys"
local uci = require "luci.model.uci".cursor()
local keyword = "ubuntu"
local util = require("luci.util")
local docker = require "luci.model.docker"
function container_status()
local docker_path = util.exec("which docker")
local docker_install = (string.len(docker_path) > 0)
local docker_running = util.exec("ps | grep dockerd | grep -v 'grep' | wc -l")
local container_id = util.trim(util.exec("docker ps -aqf 'name="..keyword.."'"))
local container_install = (string.len(container_id) > 0)
local container_running = container_install and (string.len(util.trim(util.exec("docker ps -qf 'id="..container_id.."'"))) > 0)
local port = tonumber(uci:get_first(keyword, keyword, "port", "6901"))
local status = {
docker_install = docker_install,
docker_start = docker_running,
container_id = container_id,
container_port = (port),
container_install = container_install,
container_running = container_running,
password = uci:get_first(keyword, keyword, "password", ""),
}
return status
end
function get_container_status()
local status = container_status()
luci.http.prepare_content("application/json")
luci.http.write_json(status)
end
function stop_container()
local status = container_status()
local container_id = status.container_id
util.exec("docker stop '"..container_id.."'")
end
function start_container()
local status = container_status()
local container_id = status.container_id
util.exec("docker start '"..container_id.."'")
end
function install_container()
local image = util.exec("sh /usr/share/ubuntu/install.sh -l")
local password = luci.http.formvalue("password")
local port = luci.http.formvalue("port")
uci:tset(keyword, "@"..keyword.."[0]", {
password = password or "password",
port = port or "6901",
})
uci:save(keyword)
uci:commit(keyword)
local pull_image = function(image)
docker:append_status("Images: " .. "pulling" .. " " .. image .. "...\n")
local dk = docker.new()
local res = dk.images:create({query = {fromImage=image}}, docker.pull_image_show_status_cb)
if res and res.code and res.code == 200 and (res.body[#res.body] and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. image or res.body[#res.body].status == "Status: Image is up to date for ".. image)) then
docker:append_status("done\n")
else
res.code = (res.code == 200) and 500 or res.code
docker:append_status("code:" .. res.code.." ".. (res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)).. "\n")
end
end
local install_ubuntu = function()
local os = require "os"
local fs = require "nixio.fs"
local c = ("sh /usr/share/ubuntu/install.sh -i >/tmp/log/ubuntu.stdout 2>/tmp/log/ubuntu.stderr")
-- docker:append_status(c)
local r = os.execute(c)
local e = fs.readfile("/tmp/log/ubuntu.stderr")
local o = fs.readfile("/tmp/log/ubuntu.stdout")
fs.unlink("/tmp/log/ubuntu.stderr")
fs.unlink("/tmp/log/ubuntu.stdout")
if r == 0 then
docker:append_status(o)
else
docker:append_status( e )
end
end
-- local status = {
-- shell = shell,
-- image_name = image,
-- }
-- luci.http.prepare_content("application/json")
-- luci.http.write_json(status)
if image then
docker:write_status("ubuntu installing\n")
pull_image(image)
install_ubuntu()
else
docker:write_status("ubuntu image not defined!\n")
end
end
function uninstall_container()
local status = container_status()
local container_id = status.container_id
util.exec("docker container rm '"..container_id.."'")
end
-- 总结:
-- docker是否安装
-- 容器是否安装
-- 缺少在lua和htm中运行命令的方法
-- 获取容器id docker ps -aqf'name=ubuntu'
-- 启动容器 docker start 78a8455e6d38
-- 停止容器 docker stop 78a8455e6d38
--[[
todo
--]]

View File

@ -0,0 +1,26 @@
local m, s
local uci = luci.model.uci.cursor()
local sys = require 'luci.sys'
local docker = require "luci.model.docker"
m = SimpleForm("ubuntu", translate("ubuntu"), translate("Linkease-PC是为EasePi定制的一套Ubuntu系统。纯英文系统欢迎各位极客玩家享用。")
.. translatef(" "
.. "<a href=\"%s\" target=\"_blank\">"
.. "访问官网</a>", "https://easepi.linkease.com/"))
m.submit=false
m.reset=false
s = m:section(SimpleSection)
s.template = "dockerman/apply_widget"
s.err = docker:read_status()
s.err = s.err and s.err:gsub("\n","<br>"):gsub(" ","&nbsp;")
if s.err then
docker:clear_status()
end
s=m:section(SimpleSection)
s.template = "ubuntu/ubuntu"
return m

View File

@ -0,0 +1,114 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(5,'<%=url("admin/services/ubuntu/status")%>', null,
function (x, st) {
var tb = document.getElementById('ubuntu_status');
if (st && tb) {
if (st.docker_install){
if (st.docker_start){
if (st.container_install) {
if (st.container_running) {
const htmlString = '<br/><em><%:The ubuntu service is running.%></em>'
+ "<br/><br/><input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:open ubuntu%> \" onclick=\"open_container('" + st.container_port + "')\" />"
+ "<input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:stop ubuntu%> \" onclick=\"stop_container('" + st.container_id + "')\" /><br/><br/>";
tb.innerHTML = htmlString;
}
else {
tb.innerHTML = '<br/><em><%:The ubuntu service is not running.%></em>'
+ "<br/><br/><input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:run ubuntu%> \" onclick=\"start_container('" + st.container_id + "')\" />"
+ "<input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:uninstall ubuntu%> \" onclick=\"uninstall_container('" + st.container_id + "')\" /><br/><br/>";
}
}
else {
let cache = document.getElementById('cache')
if(!cache){
var configs = [
{id: "port", label: "<%:Port (optional)%>:", value: st.container_port},
{id: "password", label: "<%:Password (optional)%>:", value: st.password},
];
tb.innerHTML = '<br/><em><%:The ubuntu service is not installed.%></em>';
configs.forEach(function(c){
tb.innerHTML += ("<div class=\"cbi-value\"><label class=\"cbi-value-title\" for=\"" + c.id + "\">" + c.label + "</label>"
+ "<div class=\"cbi-value-field\"><input type=\"text\" class=\"cbi-input-text\" id=\"" + c.id + "\" value=\"" + c.value + "\"/></div></div>");
});
tb.innerHTML += ("<div class=\"cbi-value\"><label class=\"cbi-value-title\"></label>"
+ "<div class=\"cbi-value-field\"><input class=\"btn cbi-button cbi-button-apply\" type=\"button\" value=\" <%:install ubuntu%> \" onclick=\"install_container()\" /></div></div><br>");
}
}
}
else{
tb.innerHTML = '<br/><em><%:Docker service is not start.%></em>'
}
}
else{
tb.innerHTML = '<br/><em><%:Docker is not installed.%></em>'
}
}
}
);
var xhr_post = function(url, data, cb) {
data = data || {};
data.token = '<%=token%>';
cb || docker_status_message('notice', '<img src="/luci-static/resources/icons/loading.gif" alt="" style="vertical-align:middle" />');
new XHR().post(url, data, (x, d) => {
cb || docker_status_message();
cb && cb(x, d);
});
};
function open_container(x) {
Url = "http://" + window.location.hostname + ":" + x
// alert(Url)
window.open(Url)
return false
}
const STOP_URL = '<%=luci.dispatcher.build_url("admin", "services", "ubuntu","stop")%>';
function stop_container(x) {
xhr_post(STOP_URL, { container_id: x });
return false
}
const START_URL = '<%=luci.dispatcher.build_url("admin", "services", "ubuntu","start")%>';
function start_container(x) {
xhr_post(START_URL, { container_id: x });
return false
}
const UNINSTALL_URL = '<%=luci.dispatcher.build_url("admin", "services", "ubuntu","uninstall")%>';
function uninstall_container(x) {
xhr_post(UNINSTALL_URL, { container_id: x });
return false
}
const INSTALL_URL = '<%=luci.dispatcher.build_url("admin", "services", "ubuntu","install")%>';
function install_container(x) {
let password = document.getElementById('password').value
let port = document.getElementById('port').value
xhr_post(INSTALL_URL, {password: password, port: port}, (x, d) => {
// alert(" 删除容器'" + d.image_name + "' ");
location.reload()
});
uci_confirm_docker();
return false
}
//]]></script>
<fieldset class="cbi-section">
<fieldset class="cbi-section-node" id="ubuntu_status">
<em>
<%:Collecting data...%>
</em>
</fieldset>
</fieldset>

View File

@ -0,0 +1,35 @@
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 "存储路径不能为空!"

View File

@ -0,0 +1,4 @@
config kodexplorer
option 'image' 'linkease/desktop-ubuntu-arm64:develop'
option 'password' 'password'
option 'port' '6901'

View File

@ -0,0 +1 @@
{"ignore_conditions": ["healthy"]}

View File

@ -0,0 +1,47 @@
#!/bin/sh
image_name=`uci get ubuntu.@ubuntu[0].image 2>/dev/null`
[ -z "$image_name" ] && image_name="linkease/desktop-ubuntu-arm64:develop"
install(){
local password=`uci get ubuntu.@ubuntu[0].password 2>/dev/null`
local port=`uci get ubuntu.@ubuntu[0].port 2>/dev/null`
[ -z "$password" ] && password="password"
[ -z "$port" ] && port=6901
docker run -d --name ubuntu \
--dns=223.5.5.5 -u=0:0 \
-v=/mnt:/mnt:rslave \
--net="docker-pcnet" \
--ip=10.10.100.9 \
--shm-size=512m \
-p $port:6901 \
-e VNC_PW=$password \
-e VNC_USE_HTTP=0 \
--restart unless-stopped \
$image_name
}
while getopts ":il" optname
do
case "$optname" in
"l")
echo -n $image_name
;;
"i")
install
;;
":")
echo "No argument value for option $OPTARG"
;;
"?")
echo "未知选项 $OPTARG"
;;
*)
echo "Unknown error while processing options"
;;
esac
done