add luci-app-ubuntu
This commit is contained in:
parent
b22f3e9664
commit
8441e48eea
19
applications/luci-app-ubuntu/Makefile
Normal file
19
applications/luci-app-ubuntu/Makefile
Normal 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
|
||||||
|
|
143
applications/luci-app-ubuntu/luasrc/controller/ubuntu.lua
Executable file
143
applications/luci-app-ubuntu/luasrc/controller/ubuntu.lua
Executable 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
|
||||||
|
网络请求提示框
|
||||||
|
--]]
|
26
applications/luci-app-ubuntu/luasrc/model/cbi/ubuntu/status.lua
Executable file
26
applications/luci-app-ubuntu/luasrc/model/cbi/ubuntu/status.lua
Executable 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(" "," ")
|
||||||
|
if s.err then
|
||||||
|
docker:clear_status()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
s=m:section(SimpleSection)
|
||||||
|
s.template = "ubuntu/ubuntu"
|
||||||
|
|
||||||
|
|
||||||
|
return m
|
114
applications/luci-app-ubuntu/luasrc/view/ubuntu/ubuntu.htm
Executable file
114
applications/luci-app-ubuntu/luasrc/view/ubuntu/ubuntu.htm
Executable 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>
|
35
applications/luci-app-ubuntu/po/zh-cn/ubuntu.po
Normal file
35
applications/luci-app-ubuntu/po/zh-cn/ubuntu.po
Normal 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 "存储路径不能为空!"
|
4
applications/luci-app-ubuntu/root/etc/config/ubuntu
Normal file
4
applications/luci-app-ubuntu/root/etc/config/ubuntu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
config kodexplorer
|
||||||
|
option 'image' 'linkease/desktop-ubuntu-arm64:develop'
|
||||||
|
option 'password' 'password'
|
||||||
|
option 'port' '6901'
|
1
applications/luci-app-ubuntu/root/opt/docker/jobs.json
Normal file
1
applications/luci-app-ubuntu/root/opt/docker/jobs.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"ignore_conditions": ["healthy"]}
|
47
applications/luci-app-ubuntu/root/usr/share/ubuntu/install.sh
Executable file
47
applications/luci-app-ubuntu/root/usr/share/ubuntu/install.sh
Executable 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
|
Loading…
x
Reference in New Issue
Block a user