diff options
Diffstat (limited to 'applications/luci-app-dockerman/luasrc/model')
-rw-r--r-- | applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua | 252 |
1 files changed, 145 insertions, 107 deletions
diff --git a/applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua b/applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua index 2187de4662..0d727c6e86 100644 --- a/applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua +++ b/applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua @@ -3,139 +3,171 @@ LuCI - Lua Configuration Interface Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman> ]]-- -require "luci.util" local http = require "luci.http" -local uci = luci.model.uci.cursor() local docker = require "luci.model.docker" + +local m, s, o +local images, networks, containers, res + local dk = docker.new() +res = dk.images:list() +if res.code <300 then + images = res.body +else + return +end -local images, networks, containers -local res = dk.images:list() -if res.code <300 then images = res.body else return end res = dk.networks:list() -if res.code <300 then networks = res.body else return end -res = dk.containers:list({query = {all=true}}) -if res.code <300 then containers = res.body else return end +if res.code <300 then + networks = res.body +else + return +end + +res = dk.containers:list({ + query = { + all=true + } +}) +if res.code <300 then + containers = res.body +else + return +end local urlencode = luci.http.protocol and luci.http.protocol.urlencode or luci.util.urlencode function get_containers() - local data = {} - if type(containers) ~= "table" then return nil end - for i, v in ipairs(containers) do - local index = v.Created .. v.Id - data[index]={} - data[index]["_selected"] = 0 - data[index]["_id"] = v.Id:sub(1,12) - data[index]["name"] = v.Names[1]:sub(2) - data[index]["_name"] = '<a href='..luci.dispatcher.build_url("admin/docker/container/"..v.Id)..' class="dockerman_link" title="'..translate("Container detail")..'">'.. v.Names[1]:sub(2).."</a>" - data[index]["_status"] = v.Status - if v.Status:find("^Up") then - data[index]["_status"] = '<font color="green">'.. data[index]["_status"] .. "</font>" - else - data[index]["_status"] = '<font color="red">'.. data[index]["_status"] .. "</font>" - end - if (type(v.NetworkSettings) == "table" and type(v.NetworkSettings.Networks) == "table") then - for networkname, netconfig in pairs(v.NetworkSettings.Networks) do - data[index]["_network"] = (data[index]["_network"] ~= nil and (data[index]["_network"] .." | ") or "").. networkname .. (netconfig.IPAddress ~= "" and (": " .. netconfig.IPAddress) or "") - end - end - -- networkmode = v.HostConfig.NetworkMode ~= "default" and v.HostConfig.NetworkMode or "bridge" - -- data[index]["_network"] = v.NetworkSettings.Networks[networkmode].IPAddress or nil - -- local _, _, image = v.Image:find("^sha256:(.+)") - -- if image ~= nil then - -- image=image:sub(1,12) - -- end - if v.Ports and next(v.Ports) ~= nil then - data[index]["_ports"] = nil - for _,v2 in ipairs(v.Ports) do - data[index]["_ports"] = (data[index]["_ports"] and (data[index]["_ports"] .. ", ") or "") - .. ((v2.PublicPort and v2.Type and v2.Type == "tcp") and ('<a href="javascript:void(0);" onclick="window.open((window.location.origin.match(/^(.+):\\d+$/) && window.location.origin.match(/^(.+):\\d+$/)[1] || window.location.origin) + \':\' + '.. v2.PublicPort ..', \'_blank\');">') or "") - .. (v2.PublicPort and (v2.PublicPort .. ":") or "") .. (v2.PrivatePort and (v2.PrivatePort .."/") or "") .. (v2.Type and v2.Type or "") - .. ((v2.PublicPort and v2.Type and v2.Type == "tcp")and "</a>" or "") - end - end - for ii,iv in ipairs(images) do - if iv.Id == v.ImageID then - data[index]["_image"] = iv.RepoTags and iv.RepoTags[1] or (iv.RepoDigests[1]:gsub("(.-)@.+", "%1") .. ":<none>") - end - end - - data[index]["_image_id"] = v.ImageID:sub(8,20) - data[index]["_command"] = v.Command - end - return data + local data = {} + + if type(containers) ~= "table" then + return nil + end + + for i, v in ipairs(containers) do + local index = v.Created .. v.Id + + data[index]={} + data[index]["_selected"] = 0 + data[index]["_id"] = v.Id:sub(1,12) + data[index]["name"] = v.Names[1]:sub(2) + data[index]["_name"] = '<a href='..luci.dispatcher.build_url("admin/docker/container/"..v.Id)..' class="dockerman_link" title="'..translate("Container detail")..'">'.. v.Names[1]:sub(2).."</a>" + data[index]["_status"] = v.Status + + if v.Status:find("^Up") then + data[index]["_status"] = '<font color="green">'.. data[index]["_status"] .. "</font>" + else + data[index]["_status"] = '<font color="red">'.. data[index]["_status"] .. "</font>" + end + + if (type(v.NetworkSettings) == "table" and type(v.NetworkSettings.Networks) == "table") then + for networkname, netconfig in pairs(v.NetworkSettings.Networks) do + data[index]["_network"] = (data[index]["_network"] ~= nil and (data[index]["_network"] .." | ") or "").. networkname .. (netconfig.IPAddress ~= "" and (": " .. netconfig.IPAddress) or "") + end + end + + if v.Ports and next(v.Ports) ~= nil then + data[index]["_ports"] = nil + for _,v2 in ipairs(v.Ports) do + data[index]["_ports"] = (data[index]["_ports"] and (data[index]["_ports"] .. ", ") or "") + .. ((v2.PublicPort and v2.Type and v2.Type == "tcp") and ('<a href="javascript:void(0);" onclick="window.open((window.location.origin.match(/^(.+):\\d+$/) && window.location.origin.match(/^(.+):\\d+$/)[1] || window.location.origin) + \':\' + '.. v2.PublicPort ..', \'_blank\');">') or "") + .. (v2.PublicPort and (v2.PublicPort .. ":") or "") .. (v2.PrivatePort and (v2.PrivatePort .."/") or "") .. (v2.Type and v2.Type or "") + .. ((v2.PublicPort and v2.Type and v2.Type == "tcp")and "</a>" or "") + end + end + + for ii,iv in ipairs(images) do + if iv.Id == v.ImageID then + data[index]["_image"] = iv.RepoTags and iv.RepoTags[1] or (iv.RepoDigests[1]:gsub("(.-)@.+", "%1") .. ":<none>") + end + end + + data[index]["_image_id"] = v.ImageID:sub(8,20) + data[index]["_command"] = v.Command + end + + return data end local c_lists = get_containers() --- list Containers --- m = Map("docker", translate("Docker")) + m = SimpleForm("docker", translate("Docker")) m.submit=false m.reset=false -docker_status = m:section(SimpleSection) -docker_status.template = "dockerman/apply_widget" -docker_status.err=docker:read_status() -docker_status.err=docker_status.err and docker_status.err:gsub("\n","<br>"):gsub(" "," ") -if docker_status.err then docker:clear_status() end +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 c_table = m:section(Table, c_lists, translate("Containers")) c_table.nodescr=true --- v.template = "cbi/tblsection" --- v.sortable = true + container_selecter = c_table:option(Flag, "_selected","") container_selecter.disabled = 0 container_selecter.enabled = 1 container_selecter.default = 0 +container_selecter.write=function(self, section, value) + c_lists[section]._selected = value +end container_id = c_table:option(DummyValue, "_id", translate("ID")) container_id.width="10%" + container_name = c_table:option(DummyValue, "_name", translate("Container Name")) container_name.rawhtml = true + container_status = c_table:option(DummyValue, "_status", translate("Status")) container_status.width="15%" container_status.rawhtml=true + container_ip = c_table:option(DummyValue, "_network", translate("Network")) container_ip.width="15%" + container_ports = c_table:option(DummyValue, "_ports", translate("Ports")) container_ports.width="10%" container_ports.rawhtml = true + container_image = c_table:option(DummyValue, "_image", translate("Image")) container_image.width="10%" + container_command = c_table:option(DummyValue, "_command", translate("Command")) container_command.width="20%" -container_selecter.write=function(self, section, value) - c_lists[section]._selected = value -end - local start_stop_remove = function(m,cmd) - local c_selected = {} - -- 遍历table中sectionid - local c_table_sids = c_table:cfgsections() - for _, c_table_sid in ipairs(c_table_sids) do - -- 得到选中项的名字 - if c_lists[c_table_sid]._selected == 1 then - c_selected[#c_selected+1] = c_lists[c_table_sid].name --container_name:cfgvalue(c_table_sid) - end - end - if #c_selected >0 then - docker:clear_status() - local success = true - for _,cont in ipairs(c_selected) do - docker:append_status("Containers: " .. cmd .. " " .. cont .. "...") - local res = dk.containers[cmd](dk, {id = cont}) - if res and res.code >= 300 then - success = false - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - else - docker:append_status("done\n") - end - end - if success then docker:clear_status() end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - end + local c_selected = {} + + local c_table_sids = c_table:cfgsections() + for _, c_table_sid in ipairs(c_table_sids) do + if c_lists[c_table_sid]._selected == 1 then + c_selected[#c_selected+1] = c_lists[c_table_sid].name + end + end + + if #c_selected >0 then + local success = true + + docker:clear_status() + for _,cont in ipairs(c_selected) do + docker:append_status("Containers: " .. cmd .. " " .. cont .. "...") + local res = dk.containers[cmd](dk, {id = cont}) + if res and res.code >= 300 then + success = false + docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") + else + docker:append_status("done\n") + end + end + + if success then + docker:clear_status() + end + + luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) + end end action_section = m:section(Table,{{}}) @@ -148,48 +180,54 @@ btnnew.inputtitle= translate("New") btnnew.template = "dockerman/cbi/inlinebutton" btnnew.inputstyle = "add" btnnew.forcewrite = true +btnnew.write = function(self, section) + luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) +end + btnstart=action_section:option(Button, "_start") btnstart.template = "dockerman/cbi/inlinebutton" btnstart.inputtitle=translate("Start") btnstart.inputstyle = "apply" btnstart.forcewrite = true +btnstart.write = function(self, section) + start_stop_remove(m,"start") +end + btnrestart=action_section:option(Button, "_restart") btnrestart.template = "dockerman/cbi/inlinebutton" btnrestart.inputtitle=translate("Restart") btnrestart.inputstyle = "reload" btnrestart.forcewrite = true +btnrestart.write = function(self, section) + start_stop_remove(m,"restart") +end + btnstop=action_section:option(Button, "_stop") btnstop.template = "dockerman/cbi/inlinebutton" btnstop.inputtitle=translate("Stop") btnstop.inputstyle = "reset" btnstop.forcewrite = true +btnstop.write = function(self, section) + start_stop_remove(m,"stop") +end + + btnkill=action_section:option(Button, "_kill") btnkill.template = "dockerman/cbi/inlinebutton" btnkill.inputtitle=translate("Kill") btnkill.inputstyle = "reset" btnkill.forcewrite = true +btnkill.write = function(self, section) + start_stop_remove(m,"kill") +end + btnremove=action_section:option(Button, "_remove") btnremove.template = "dockerman/cbi/inlinebutton" btnremove.inputtitle=translate("Remove") btnremove.inputstyle = "remove" btnremove.forcewrite = true -btnnew.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) -end -btnstart.write = function(self, section) - start_stop_remove(m,"start") -end -btnrestart.write = function(self, section) - start_stop_remove(m,"restart") -end btnremove.write = function(self, section) - start_stop_remove(m,"remove") -end -btnstop.write = function(self, section) - start_stop_remove(m,"stop") -end -btnkill.write = function(self, section) - start_stop_remove(m,"kill") + start_stop_remove(m,"remove") end return m |