luci-app-dockerman: sync with upstream source

This commit is contained in:
CN_SZTL 2020-02-08 21:52:03 +08:00
parent 2505cf346c
commit 40345ce2a4
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
4 changed files with 211 additions and 95 deletions

View File

@ -4,6 +4,7 @@ Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
]]--
require "luci.util"
require "math"
local uci = luci.model.uci.cursor()
local docker = require "luci.model.docker"
local dk = docker.new()
@ -14,10 +15,23 @@ local images = dk.images:list().body
local networks = dk.networks:list().body
local containers = dk.containers:list(nil, {all=true}).body
local is_quot_complete = function(str)
if not str then return true end
local num = 0, w
for w in str:gmatch("[\"\']") do
num = num + 1
end
if math.fmod(num, 2) ~= 0 then
return false
else
return true
end
end
-- reslvo default config
local default_config = { }
if cmd_line and cmd_line:match("^docker.+") then
local key = nil
local key = nil, _key
--cursor = 0: docker run
--cursor = 1: resloving para
--cursor = 2: resloving image
@ -26,6 +40,24 @@ if cmd_line and cmd_line:match("^docker.+") then
for w in cmd_line:gmatch("[^%s]+") do
-- skip '\'
if w == '\\' then
elseif _key then
-- there is a value that unpair quotation marks:
-- "i was a ok man"
-- now we only get: "i
if _key == "mount" or _key == "link" or _key == "env" or _key == "dns" or _key == "port" or _key == "device" or _key == "tmpfs" then
default_config[_key][#default_config[_key]] = default_config[_key][#default_config[_key]] .. " " .. w
if is_quot_complete(default_config[_key][#default_config[_key]]) then
-- clear quotation marks
default_config[_key][#default_config[_key]] = default_config[_key][#default_config[_key]]:gsub("[\"\']", "")
_key = nil
end
else
default_config[_key] = default_config[_key] .. " ".. w
if is_quot_complete(default_config[_key]) then
default_config[_key] = default_config[_key]:gsub("[\"\']", "")
_key = nil
end
end
-- start with '-'
elseif w:match("^%-+.+") and cursor <= 1 then
--key=value
@ -33,7 +65,7 @@ if cmd_line and cmd_line:match("^docker.+") then
key, val = w:match("^%-%-(.-)=(.+)")
-- -dit
if not key then key = w:match("^%-%-(.+)") end
if not key then
key = w:match("^%-(.+)")
if key:match("i") or key:match("t") or key:match("d") then
@ -43,7 +75,7 @@ if cmd_line and cmd_line:match("^docker.+") then
key = nil
end
end
if key == "v" or key == "volume" then
key = "mount"
elseif key == "p" then
@ -72,6 +104,12 @@ if cmd_line and cmd_line:match("^docker.+") then
else
default_config[key] = val
end
-- if there are " or ' in val and separate by space, we need keep the _key to link with next w
if is_quot_complete(val) then
_key = nil
else
_key = key
end
-- clear key
key = nil
end
@ -87,6 +125,12 @@ if cmd_line and cmd_line:match("^docker.+") then
if key == "cpus" or key == "cpushare" or key == "memory" or key == "blkioweight" or key == "device" or key == "tmpfs" then
default_config["advance"] = 1
end
-- if there are " or ' in val and separate by space, we need keep the _key to link with next w
if is_quot_complete(w) then
_key = nil
else
_key = key
end
key = nil
cursor = 1
--image and command

View File

@ -1,57 +1,57 @@
<style type="text/css">
#docker_apply_overlay {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
display: none;
z-index: 20000;
}
#docker_apply_overlay {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
display: none;
z-index: 20000;
}
#docker_apply_overlay .alert-message {
position: relative;
top: 10%;
width: 60%;
margin: auto;
display: flex;
flex-wrap: wrap;
min-height: 32px;
align-items: center;
}
#docker_apply_overlay .alert-message {
position: relative;
top: 10%;
width: 60%;
margin: auto;
display: flex;
flex-wrap: wrap;
min-height: 32px;
align-items: center;
}
#docker_apply_overlay .alert-message > h4,
#docker_apply_overlay .alert-message > p,
#docker_apply_overlay .alert-message > div {
flex-basis: 100%;
}
#docker_apply_overlay .alert-message > h4,
#docker_apply_overlay .alert-message > p,
#docker_apply_overlay .alert-message > div {
flex-basis: 100%;
}
#docker_apply_overlay .alert-message > img {
margin-right: 1em;
flex-basis: 32px;
}
#docker_apply_overlay .alert-message > img {
margin-right: 1em;
flex-basis: 32px;
}
body.apply-overlay-active {
overflow: hidden;
height: 100vh;
}
body.apply-overlay-active {
overflow: hidden;
height: 100vh;
}
body.apply-overlay-active #docker_apply_overlay {
display: block;
}
body.apply-overlay-active #docker_apply_overlay {
display: block;
}
</style>
<script type="text/javascript">//<![CDATA[
var xhr = new XHR(),
uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
was_xhr_poll_running = false;
var xhr = new XHR(),
uci_apply_rollback = <%=math.max(luci.config and luci.config.apply and luci.config.apply.rollback or 30, 30)%>,
uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>,
uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>,
uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>,
was_xhr_poll_running = false;
function docker_status_message(type, content) {
document.getElementById('docker_apply_overlay') || document.body.insertAdjacentHTML("beforeend",'<div id="docker_apply_overlay"><div class="alert-message"></div></div>')
var overlay = document.getElementById('docker_apply_overlay')
var overlay = document.getElementById('docker_apply_overlay')
message = overlay.querySelector('.alert-message');
if (message && type) {
@ -65,7 +65,7 @@ function docker_status_message(type, content) {
message.innerHTML = content;
document.body.classList.add('apply-overlay-active');
document.body.scrollTop = document.documentElement.scrollTop = 0;
if (!was_xhr_poll_running) {
was_xhr_poll_running = XHR.running();
XHR.halt();
@ -80,58 +80,53 @@ function docker_status_message(type, content) {
}
var loading_msg="Loadding.."
function uci_confirm_docker() {
var tt;
docker_status_message('notice');
var call = function(r, resjson, duration) {
var tt;
docker_status_message('notice');
var call = function(r, resjson, duration) {
if (r && r.status === 200 ) {
var indicator = document.querySelector('.uci_change_indicator');
if (indicator) indicator.style.display = 'none';
docker_status_message('notice', '<%:Docker actions done.%>');
window.clearTimeout(tt);
return;
}
loading_msg = resjson?resjson.info:loading_msg
// var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
var delay =1000
window.setTimeout(function() {
xhr.get('<%=url("admin/docker/confirm")%>', null, call, uci_apply_timeout * 1000);
}, delay);
};
var indicator = document.querySelector('.uci_change_indicator');
if (indicator) indicator.style.display = 'none';
docker_status_message('notice', '<%:Docker actions done.%>');
window.clearTimeout(tt);
return;
}
loading_msg = resjson?resjson.info:loading_msg
// var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0);
var delay =1000
window.setTimeout(function() {
xhr.get('<%=url("admin/docker/confirm")%>', null, call, uci_apply_timeout * 1000);
}, delay);
};
var tick = function() {
var now = Date.now();
var tick = function() {
var now = Date.now();
docker_status_message('notice',
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
loading_msg);
docker_status_message('notice',
'<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' +
loading_msg);
tt = window.setTimeout(tick, 200);
ts = now;
};
tick();
/* wait a few seconds for the settings to become effective */
window.setTimeout(call, Math.max(uci_apply_holdoff * 1000 , 1));
}
// document.getElementsByTagName("form")[0].addEventListener("submit", (e)=>{
// uci_confirm_docker()
// })
tt = window.setTimeout(tick, 200);
ts = now;
};
tick();
/* wait a few seconds for the settings to become effective */
window.setTimeout(call, Math.max(uci_apply_holdoff * 1000 , 1));
}
// document.getElementsByTagName("form")[0].addEventListener("submit", (e)=>{
// uci_confirm_docker()
// })
function fnSubmitForm(el){
if (el.id != "cbid.table.1._new") {
uci_confirm_docker()
}
uci_confirm_docker()
}
}
<% if self.err then -%>
docker_status_message('warning', `<%=self.err%>`);
document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
docker_status_message()
})
docker_status_message('warning', `<%=self.err%>`);
document.getElementById('docker_apply_overlay').addEventListener("click", (e)=>{
docker_status_message()
})
<%- end %>
window.onload= function (){

View File

@ -1,20 +1,91 @@
<%+cbi/valueheader%>
<style type="text/css">
#dialog_reslov {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
display: none;
z-index: 20000;
}
#dialog_reslov .dialog_box {
position: relative;
background: rgba(255, 255, 255);
top: 10%;
width: 50%;
margin: auto;
display: flex;
flex-wrap: wrap;
min-height: 50%;
max-height: auto;
align-items: center;
}
#dialog_reslov .dialog_line {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 20px;
margin-right: 20px;
}
#dialog_reslov .dialog_box>h4,
#dialog_reslov .dialog_box>p,
#dialog_reslov .dialog_box>div {
flex-basis: 100%;
}
#dialog_reslov .dialog_box>img {
margin-right: 1em;
flex-basis: 32px;
}
body.dialog-reslov-active {
overflow: hidden;
height: 100vh;
}
body.dialog-reslov-active #dialog_reslov {
display: block;
}
</style>
<script type="text/javascript">
function resolv_container(op) {
function close_reslov_dialog() {
document.body.classList.remove('dialog-reslov-active');
document.documentElement.style.overflowY = 'scroll';
}
function reslov_container(op) {
let s = document.getElementById(op + '-status');
if (!s) return;
let cmd_line = prompt("<%:Plese input <docker create/run> command line:%>", "");
let cmd_line = document.getElementById("dialog_reslov_text").value;
if (cmd_line == null || cmd_line == "") {
s.innerHTML = "<font color='red'>Canceled</font>";
s.innerHTML = "<font color='red'><%:Canceled%></font>";
close_reslov_dialog()
return;
}
if (! cmd_line.match("^docker")) {
s.innerHTML = "<font color='red'>Command line Error</font>";
if (!cmd_line.match(/^docker\s+(run|create)/)) {
s.innerHTML = "<font color='red'><%:Command line Error%></font>";
close_reslov_dialog()
return;
}
let reg_space = /\s+/g
let reg_muti_line= /\\\s*\n/g
let reg_rem =/(?<!\\)`#.+(?<!\\)`/g // the command has `# `
cmd_line = cmd_line.replace(reg_rem, " ").replace(reg_muti_line, " ").replace(reg_space, " ")
console.log(cmd_line)
window.location.href = "/cgi-bin/luci/admin/docker/newcontainer/" + encodeURI(cmd_line)
}
function show_reslov_dialog(op) {
document.getElementById('dialog_reslov') || document.body.insertAdjacentHTML("beforeend", '<div id="dialog_reslov"><div class="dialog_box"><div class="dialog_line"></div><div class="dialog_line"><h5><%:Plese input <docker create/run> command line:%></h5></div><div class="dialog_line"><textarea class="cbi-input-textarea" id="dialog_reslov_text" style="width: 100%; height:100%;" rows="15"></textarea></div><div class="dialog_line"><input type="button" class="cbi-button cbi-button-apply" type="submit" value="<%:Submit%>" onclick="reslov_container(\'' + op + '\')" /> <input type="button" class="cbi-button cbi-button-reset" type="reset" value="<%:Cancel%>" onclick="close_reslov_dialog()" /></div></div></div>')
document.body.classList.add('dialog-reslov-active');
document.documentElement.style.overflowY = 'hidden';
}
</script>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Command line%>" onclick="resolv_container('<%=self.option%>')" />
<input type="button" class="cbi-button cbi-button-apply" value="<%:Command line%>"
onclick="show_reslov_dialog('<%=self.option%>')" />
<span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%>

View File

@ -324,3 +324,9 @@ msgstr "设备"
msgid "Finish Time"
msgstr "结束时间"
msgid "Command line Error"
msgstr "命令行错误"
msgid "Canceled"
msgstr "已取消"