luci-app-dockerman: controller/docker refactoring and update coding style
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
This commit is contained in:
parent
94bcd70e97
commit
10e6f62904
1 changed files with 382 additions and 324 deletions
|
@ -2,14 +2,12 @@
|
||||||
LuCI - Lua Configuration Interface
|
LuCI - Lua Configuration Interface
|
||||||
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
|
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
|
||||||
]]--
|
]]--
|
||||||
require "luci.util"
|
|
||||||
local docker = require "luci.model.docker"
|
local docker = require "luci.model.docker"
|
||||||
-- local uci = require "luci.model.uci"
|
|
||||||
|
|
||||||
module("luci.controller.dockerman",package.seeall)
|
module("luci.controller.dockerman",package.seeall)
|
||||||
|
|
||||||
function index()
|
function index()
|
||||||
|
|
||||||
local e = entry({"admin", "docker"}, firstchild(), "Docker", 40)
|
local e = entry({"admin", "docker"}, firstchild(), "Docker", 40)
|
||||||
e.dependent = false
|
e.dependent = false
|
||||||
e.acl_depends = { "luci-app-dockerman" }
|
e.acl_depends = { "luci-app-dockerman" }
|
||||||
|
@ -19,22 +17,31 @@ function index()
|
||||||
local remote = luci.model.uci.cursor():get("dockerd", "globals", "remote_endpoint")
|
local remote = luci.model.uci.cursor():get("dockerd", "globals", "remote_endpoint")
|
||||||
if remote == nil then
|
if remote == nil then
|
||||||
local socket = luci.model.uci.cursor():get("dockerd", "globals", "socket_path")
|
local socket = luci.model.uci.cursor():get("dockerd", "globals", "socket_path")
|
||||||
if socket and not nixio.fs.access(socket) then return end
|
if socket and not nixio.fs.access(socket) then
|
||||||
|
return
|
||||||
|
end
|
||||||
elseif remote == "true" then
|
elseif remote == "true" then
|
||||||
local host = luci.model.uci.cursor():get("dockerd", "globals", "remote_host")
|
local host = luci.model.uci.cursor():get("dockerd", "globals", "remote_host")
|
||||||
local port = luci.model.uci.cursor():get("dockerd", "globals", "remote_port")
|
local port = luci.model.uci.cursor():get("dockerd", "globals", "remote_port")
|
||||||
if not host or not port then return end
|
if not host or not port then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (require "luci.model.docker").new():_ping().code ~= 200 then
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if (require "luci.model.docker").new():_ping().code ~= 200 then return end
|
|
||||||
entry({"admin", "docker", "containers"}, form("dockerman/containers"), _("Containers"),1).leaf=true
|
entry({"admin", "docker", "containers"}, form("dockerman/containers"), _("Containers"),1).leaf=true
|
||||||
entry({"admin", "docker", "images"}, form("dockerman/images"), _("Images"),2).leaf=true
|
entry({"admin", "docker", "images"}, form("dockerman/images"), _("Images"),2).leaf=true
|
||||||
entry({"admin", "docker", "networks"}, form("dockerman/networks"), _("Networks"),3).leaf=true
|
entry({"admin", "docker", "networks"}, form("dockerman/networks"), _("Networks"),3).leaf=true
|
||||||
entry({"admin", "docker", "volumes"}, form("dockerman/volumes"), _("Volumes"),4).leaf=true
|
entry({"admin", "docker", "volumes"}, form("dockerman/volumes"), _("Volumes"),4).leaf=true
|
||||||
entry({"admin", "docker", "events"}, call("action_events"), _("Events"),5)
|
entry({"admin", "docker", "events"}, call("action_events"), _("Events"),5)
|
||||||
|
|
||||||
entry({"admin", "docker", "newcontainer"}, form("dockerman/newcontainer")).leaf=true
|
entry({"admin", "docker", "newcontainer"}, form("dockerman/newcontainer")).leaf=true
|
||||||
entry({"admin", "docker", "newnetwork"}, form("dockerman/newnetwork")).leaf=true
|
entry({"admin", "docker", "newnetwork"}, form("dockerman/newnetwork")).leaf=true
|
||||||
entry({"admin", "docker", "container"}, form("dockerman/container")).leaf=true
|
entry({"admin", "docker", "container"}, form("dockerman/container")).leaf=true
|
||||||
|
|
||||||
entry({"admin", "docker", "container_stats"}, call("action_get_container_stats")).leaf=true
|
entry({"admin", "docker", "container_stats"}, call("action_get_container_stats")).leaf=true
|
||||||
entry({"admin", "docker", "container_get_archive"}, call("download_archive")).leaf=true
|
entry({"admin", "docker", "container_get_archive"}, call("download_archive")).leaf=true
|
||||||
entry({"admin", "docker", "container_put_archive"}, call("upload_archive")).leaf=true
|
entry({"admin", "docker", "container_put_archive"}, call("upload_archive")).leaf=true
|
||||||
|
@ -49,10 +56,12 @@ end
|
||||||
|
|
||||||
function action_events()
|
function action_events()
|
||||||
local logs = ""
|
local logs = ""
|
||||||
local dk = docker.new()
|
|
||||||
local query ={}
|
local query ={}
|
||||||
|
|
||||||
|
local dk = docker.new()
|
||||||
query["until"] = os.time()
|
query["until"] = os.time()
|
||||||
local events = dk:events({query = query})
|
local events = dk:events({query = query})
|
||||||
|
|
||||||
if events.code == 200 then
|
if events.code == 200 then
|
||||||
for _, v in ipairs(events.body) do
|
for _, v in ipairs(events.body) do
|
||||||
if v and v.Type == "container" then
|
if v and v.Type == "container" then
|
||||||
|
@ -64,40 +73,42 @@ function action_events()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.template.render("dockerman/logs", {self={syslog = logs, title="Events"}})
|
luci.template.render("dockerman/logs", {self={syslog = logs, title="Events"}})
|
||||||
end
|
end
|
||||||
|
|
||||||
local calculate_cpu_percent = function(d)
|
local calculate_cpu_percent = function(d)
|
||||||
if type(d) ~= "table" then return end
|
if type(d) ~= "table" then
|
||||||
cpu_count = tonumber(d["cpu_stats"]["online_cpus"])
|
return
|
||||||
cpu_percent = 0.0
|
end
|
||||||
cpu_delta = tonumber(d["cpu_stats"]["cpu_usage"]["total_usage"]) - tonumber(d["precpu_stats"]["cpu_usage"]["total_usage"])
|
|
||||||
system_delta = tonumber(d["cpu_stats"]["system_cpu_usage"]) - tonumber(d["precpu_stats"]["system_cpu_usage"])
|
local cpu_count = tonumber(d["cpu_stats"]["online_cpus"])
|
||||||
|
local cpu_percent = 0.0
|
||||||
|
local cpu_delta = tonumber(d["cpu_stats"]["cpu_usage"]["total_usage"]) - tonumber(d["precpu_stats"]["cpu_usage"]["total_usage"])
|
||||||
|
local system_delta = tonumber(d["cpu_stats"]["system_cpu_usage"]) - tonumber(d["precpu_stats"]["system_cpu_usage"])
|
||||||
if system_delta > 0.0 then
|
if system_delta > 0.0 then
|
||||||
cpu_percent = string.format("%.2f", cpu_delta / system_delta * 100.0 * cpu_count)
|
cpu_percent = string.format("%.2f", cpu_delta / system_delta * 100.0 * cpu_count)
|
||||||
end
|
end
|
||||||
-- return cpu_percent .. "%"
|
|
||||||
return cpu_percent
|
return cpu_percent
|
||||||
end
|
end
|
||||||
|
|
||||||
local get_memory = function(d)
|
local get_memory = function(d)
|
||||||
if type(d) ~= "table" then return end
|
if type(d) ~= "table" then
|
||||||
-- local limit = string.format("%.2f", tonumber(d["memory_stats"]["limit"]) / 1024 / 1024)
|
return
|
||||||
-- local usage = string.format("%.2f", (tonumber(d["memory_stats"]["usage"]) - tonumber(d["memory_stats"]["stats"]["total_cache"])) / 1024 / 1024)
|
end
|
||||||
-- return usage .. "MB / " .. limit.. "MB"
|
|
||||||
local limit =tonumber(d["memory_stats"]["limit"])
|
local limit =tonumber(d["memory_stats"]["limit"])
|
||||||
local usage = tonumber(d["memory_stats"]["usage"]) - tonumber(d["memory_stats"]["stats"]["total_cache"])
|
local usage = tonumber(d["memory_stats"]["usage"]) - tonumber(d["memory_stats"]["stats"]["total_cache"])
|
||||||
|
|
||||||
return usage, limit
|
return usage, limit
|
||||||
end
|
end
|
||||||
|
|
||||||
local get_rx_tx = function(d)
|
local get_rx_tx = function(d)
|
||||||
if type(d) ~="table" then return end
|
if type(d) ~="table" then
|
||||||
-- local data
|
return
|
||||||
-- if type(d["networks"]) == "table" then
|
end
|
||||||
-- for e, v in pairs(d["networks"]) do
|
|
||||||
-- data = (data and (data .. "<br>") or "") .. e .. " Total Tx:" .. string.format("%.2f",(tonumber(v.tx_bytes)/1024/1024)) .. "MB Total Rx: ".. string.format("%.2f",(tonumber(v.rx_bytes)/1024/1024)) .. "MB"
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
local data = {}
|
local data = {}
|
||||||
if type(d["networks"]) == "table" then
|
if type(d["networks"]) == "table" then
|
||||||
for e, v in pairs(d["networks"]) do
|
for e, v in pairs(d["networks"]) do
|
||||||
|
@ -107,6 +118,7 @@ local get_rx_tx = function(d)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return data
|
return data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,6 +177,7 @@ function action_confirm()
|
||||||
msg = "finish"
|
msg = "finish"
|
||||||
data = "finish"
|
data = "finish"
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.status(code, msg)
|
luci.http.status(code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json({info = data})
|
luci.http.write_json({info = data})
|
||||||
|
@ -193,7 +206,12 @@ function download_archive()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local res = dk.containers:get_archive({id = id, query = {path = path}}, cb)
|
local res = dk.containers:get_archive({
|
||||||
|
id = id,
|
||||||
|
query = {
|
||||||
|
path = path
|
||||||
|
}
|
||||||
|
}, cb)
|
||||||
end
|
end
|
||||||
|
|
||||||
function upload_archive(container_id)
|
function upload_archive(container_id)
|
||||||
|
@ -209,7 +227,14 @@ function upload_archive(container_id)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local res = dk.containers:put_archive({id = container_id, query = {path = path}, body = rec_send})
|
local res = dk.containers:put_archive({
|
||||||
|
id = container_id,
|
||||||
|
query = {
|
||||||
|
path = path
|
||||||
|
},
|
||||||
|
body = rec_send
|
||||||
|
})
|
||||||
|
|
||||||
local msg = res and res.body and res.body.message or nil
|
local msg = res and res.body and res.body.message or nil
|
||||||
luci.http.status(res.code, msg)
|
luci.http.status(res.code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
|
@ -238,9 +263,16 @@ function save_images(container_id)
|
||||||
luci.ltn12.pump.all(chunk, luci.http.write)
|
luci.ltn12.pump.all(chunk, luci.http.write)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
docker:write_status("Images: saving" .. " " .. container_id .. "...")
|
docker:write_status("Images: saving" .. " " .. container_id .. "...")
|
||||||
local res = dk.images:get({id = container_id, query = {names = names}}, cb)
|
local res = dk.images:get({
|
||||||
|
id = container_id,
|
||||||
|
query = {
|
||||||
|
names = names
|
||||||
|
}
|
||||||
|
}, cb)
|
||||||
docker:clear_status()
|
docker:clear_status()
|
||||||
|
|
||||||
local msg = res and res.body and res.body.message or nil
|
local msg = res and res.body and res.body.message or nil
|
||||||
luci.http.status(res.code, msg)
|
luci.http.status(res.code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
|
@ -262,7 +294,6 @@ function load_images()
|
||||||
|
|
||||||
docker:write_status("Images: loading...")
|
docker:write_status("Images: loading...")
|
||||||
local res = dk.images:load({body = rec_send})
|
local res = dk.images:load({body = rec_send})
|
||||||
-- res.body = {"stream":"Loaded image ID: sha256:1399d3d81f80d68832e85ed6ba5f94436ca17966539ba715f661bd36f3caf08f\n"}
|
|
||||||
local msg = res and res.body and ( res.body.message or res.body.stream or res.body.error ) or nil
|
local msg = res and res.body and ( res.body.message or res.body.stream or res.body.error ) or nil
|
||||||
if res.code == 200 and msg and msg:match("Loaded image ID") then
|
if res.code == 200 and msg and msg:match("Loaded image ID") then
|
||||||
docker:clear_status()
|
docker:clear_status()
|
||||||
|
@ -271,6 +302,7 @@ function load_images()
|
||||||
docker:append_status("code:" .. res.code.." ".. msg)
|
docker:append_status("code:" .. res.code.." ".. msg)
|
||||||
luci.http.status(300, msg)
|
luci.http.status(300, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json({message = msg})
|
luci.http.write_json({message = msg})
|
||||||
end
|
end
|
||||||
|
@ -280,6 +312,7 @@ function import_images()
|
||||||
local itag = luci.http.formvalue("tag")
|
local itag = luci.http.formvalue("tag")
|
||||||
local dk = docker.new()
|
local dk = docker.new()
|
||||||
local ltn12 = require "luci.ltn12"
|
local ltn12 = require "luci.ltn12"
|
||||||
|
|
||||||
local rec_send = function(sinkout)
|
local rec_send = function(sinkout)
|
||||||
luci.http.setfilehandler(function (meta, chunk, eof)
|
luci.http.setfilehandler(function (meta, chunk, eof)
|
||||||
if chunk then
|
if chunk then
|
||||||
|
@ -287,23 +320,32 @@ function import_images()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
docker:write_status("Images: importing".. " ".. itag .."...\n")
|
docker:write_status("Images: importing".. " ".. itag .."...\n")
|
||||||
local repo = itag and itag:match("^([^:]+)")
|
local repo = itag and itag:match("^([^:]+)")
|
||||||
local tag = itag and itag:match("^[^:]-:([^:]+)")
|
local tag = itag and itag:match("^[^:]-:([^:]+)")
|
||||||
local res = dk.images:create({query = {fromSrc = src or "-", repo = repo or nil, tag = tag or nil }, body = not src and rec_send or nil}, docker.import_image_show_status_cb)
|
local res = dk.images:create({
|
||||||
|
query = {
|
||||||
|
fromSrc = src or "-",
|
||||||
|
repo = repo or nil,
|
||||||
|
tag = tag or nil
|
||||||
|
},
|
||||||
|
body = not src and rec_send or nil
|
||||||
|
}, docker.import_image_show_status_cb)
|
||||||
|
|
||||||
local msg = res and res.body and ( res.body.message )or nil
|
local msg = res and res.body and ( res.body.message )or nil
|
||||||
if not msg and #res.body == 0 then
|
if not msg and #res.body == 0 then
|
||||||
-- res.body = {"status":"sha256:d5304b58e2d8cc0a2fd640c05cec1bd4d1229a604ac0dd2909f13b2b47a29285"}
|
|
||||||
msg = res.body.status or res.body.error
|
msg = res.body.status or res.body.error
|
||||||
elseif not msg and #res.body >= 1 then
|
elseif not msg and #res.body >= 1 then
|
||||||
-- res.body = [...{"status":"sha256:d5304b58e2d8cc0a2fd640c05cec1bd4d1229a604ac0dd2909f13b2b47a29285"}]
|
|
||||||
msg = res.body[#res.body].status or res.body[#res.body].error
|
msg = res.body[#res.body].status or res.body[#res.body].error
|
||||||
end
|
end
|
||||||
|
|
||||||
if res.code == 200 and msg and msg:match("sha256:") then
|
if res.code == 200 and msg and msg:match("sha256:") then
|
||||||
docker:clear_status()
|
docker:clear_status()
|
||||||
else
|
else
|
||||||
docker:append_status("code:" .. res.code.." ".. msg)
|
docker:append_status("code:" .. res.code.." ".. msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.status(res.code, msg)
|
luci.http.status(res.code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json({message = msg})
|
luci.http.write_json({message = msg})
|
||||||
|
@ -316,11 +358,15 @@ function get_image_tags(image_id)
|
||||||
luci.http.write_json({message = "no image id"})
|
luci.http.write_json({message = "no image id"})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local dk = docker.new()
|
local dk = docker.new()
|
||||||
local res = dk.images:inspect({id = image_id})
|
local res = dk.images:inspect({
|
||||||
|
id = image_id
|
||||||
|
})
|
||||||
local msg = res and res.body and res.body.message or nil
|
local msg = res and res.body and res.body.message or nil
|
||||||
luci.http.status(res.code, msg)
|
luci.http.status(res.code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
|
|
||||||
if res.code == 200 then
|
if res.code == 200 then
|
||||||
local tags = res.body.RepoTags
|
local tags = res.body.RepoTags
|
||||||
luci.http.write_json({tags = tags})
|
luci.http.write_json({tags = tags})
|
||||||
|
@ -333,19 +379,28 @@ end
|
||||||
function tag_image(image_id)
|
function tag_image(image_id)
|
||||||
local src = luci.http.formvalue("tag")
|
local src = luci.http.formvalue("tag")
|
||||||
local image_id = image_id or luci.http.formvalue("id")
|
local image_id = image_id or luci.http.formvalue("id")
|
||||||
|
|
||||||
if type(src) ~= "string" or not image_id then
|
if type(src) ~= "string" or not image_id then
|
||||||
luci.http.status(400, "no image id or tag")
|
luci.http.status(400, "no image id or tag")
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json({message = "no image id or tag"})
|
luci.http.write_json({message = "no image id or tag"})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local repo = src:match("^([^:]+)")
|
local repo = src:match("^([^:]+)")
|
||||||
local tag = src:match("^[^:]-:([^:]+)")
|
local tag = src:match("^[^:]-:([^:]+)")
|
||||||
local dk = docker.new()
|
local dk = docker.new()
|
||||||
local res = dk.images:tag({id = image_id, query={repo=repo, tag=tag}})
|
local res = dk.images:tag({
|
||||||
|
id = image_id,
|
||||||
|
query={
|
||||||
|
repo=repo,
|
||||||
|
tag=tag
|
||||||
|
}
|
||||||
|
})
|
||||||
local msg = res and res.body and res.body.message or nil
|
local msg = res and res.body and res.body.message or nil
|
||||||
luci.http.status(res.code, msg)
|
luci.http.status(res.code, msg)
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
|
|
||||||
if res.code == 201 then
|
if res.code == 201 then
|
||||||
local tags = res.body.RepoTags
|
local tags = res.body.RepoTags
|
||||||
luci.http.write_json({tags = tags})
|
luci.http.write_json({tags = tags})
|
||||||
|
@ -357,14 +412,17 @@ end
|
||||||
|
|
||||||
function untag_image(tag)
|
function untag_image(tag)
|
||||||
local tag = tag or luci.http.formvalue("tag")
|
local tag = tag or luci.http.formvalue("tag")
|
||||||
|
|
||||||
if not tag then
|
if not tag then
|
||||||
luci.http.status(400, "no tag name")
|
luci.http.status(400, "no tag name")
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json({message = "no tag name"})
|
luci.http.write_json({message = "no tag name"})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local dk = docker.new()
|
local dk = docker.new()
|
||||||
local res = dk.images:inspect({name = tag})
|
local res = dk.images:inspect({name = tag})
|
||||||
|
|
||||||
if res.code == 200 then
|
if res.code == 200 then
|
||||||
local tags = res.body.RepoTags
|
local tags = res.body.RepoTags
|
||||||
if #tags > 1 then
|
if #tags > 1 then
|
||||||
|
|
Loading…
Reference in a new issue