v0.5.23-2 2021.9.4

This commit is contained in:
SirPdboy 2021-09-04 09:46:01 +08:00 committed by GitHub
parent 1bdfc625cc
commit 9ea7d36cd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 568 additions and 400 deletions

View File

@ -10,7 +10,7 @@ module("luci.controller.dockerman",package.seeall)
function index()
entry({"admin", "services", "docker"},
alias("admin", "services", "docker", "overview"),
alias("admin", "services", "docker", "config"),
_("Docker"),
40).acl_depends = { "luci-app-dockerman" }
@ -45,7 +45,8 @@ function index()
entry({"admin", "services","docker", "newnetwork"}, form("dockerman/newnetwork")).leaf=true
entry({"admin", "services","docker", "container"}, form("dockerman/container")).leaf=true
entry({"admin", "services","docker", "container_stats"}, call("action_get_container_stats")).leaf=true
entry({"admin", "services", "container_stats"}, call("action_get_container_stats")).leaf=true
entry({"admin", "services","docker", "containers_stats"}, call("action_get_containers_stats")).leaf=true
entry({"admin", "services","docker", "container_get_archive"}, call("download_archive")).leaf=true
entry({"admin", "services","docker", "container_put_archive"}, call("upload_archive")).leaf=true
entry({"admin", "services","docker","container_list_file"},call("list_file")).leaf=true
@ -206,7 +207,7 @@ local calculate_cpu_percent = function(d)
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"])
local system_delta = tonumber(d["cpu_stats"]["system_cpu_usage"]) -- tonumber(d["precpu_stats"]["system_cpu_usage"])
if system_delta > 0.0 then
cpu_percent = string.format("%.2f", cpu_delta / system_delta * 100.0 * cpu_count)
end
@ -222,7 +223,6 @@ local get_memory = function(d)
-- local limit = string.format("%.2f", tonumber(d["memory_stats"]["limit"]) / 1024 / 1024)
-- local usage = string.format("%.2f", (tonumber(d["memory_stats"]["usage"]) - tonumber(d["memory_stats"]["stats"]["total_cache"])) / 1024 / 1024)
-- return usage .. "MB / " .. limit.. "MB"
-- luci.util.perror(luci.jsonc.stringify(d))
local limit =tonumber(d["memory_stats"]["limit"])
local usage = tonumber(d["memory_stats"]["usage"])
@ -249,49 +249,59 @@ local get_rx_tx = function(d)
return data
end
function action_get_container_stats(container_id)
local function get_stat(container_id)
if container_id then
local dk = docker.new()
local response = dk.containers:inspect({id = container_id})
if response.code == 200 and response.body.State.Running then
response = dk.containers:stats({id = container_id, query = {stream = false}})
response = dk.containers:stats({id = container_id, query = {stream = false, ["one-shot"] = true}})
if response.code == 200 then
local container_stats = response.body
local cpu_percent = calculate_cpu_percent(container_stats)
local mem_useage, mem_limit = get_memory(container_stats)
local bw_rxtx = get_rx_tx(container_stats)
luci.http.status(response.code, response.body.message)
luci.http.prepare_content("application/json")
luci.http.write_json({
return response.code, response.body.message, {
cpu_percent = cpu_percent,
memory = {
mem_useage = mem_useage,
mem_limit = mem_limit
},
bw_rxtx = bw_rxtx
})
}
else
luci.http.status(response.code, response.body.message)
luci.http.prepare_content("text/plain")
luci.http.write(response.body.message)
return response.code, response.body.message
end
else
if response.code == 200 then
luci.http.status(500, "container "..container_id.." not running")
luci.http.prepare_content("text/plain")
luci.http.write("Container "..container_id.." not running")
return 500, "container "..container_id.." not running"
else
luci.http.status(response.code, response.body.message)
luci.http.prepare_content("text/plain")
luci.http.write(response.body.message)
return response.code, response.body.message
end
end
else
luci.http.status(404, "No container name or id")
luci.http.prepare_content("text/plain")
luci.http.write("No container name or id")
return 404, "No container name or id"
end
end
function action_get_container_stats(container_id)
local code, msg, res = get_stat(container_id)
luci.http.status(code, msg)
luci.http.prepare_content("application/json")
luci.http.write_json(res)
end
function action_get_containers_stats()
local res = luci.http.formvalue(containers) or ""
local stats = {}
res = luci.jsonc.parse(res.containers)
if res and type(res) == "table" then
for i, v in ipairs(res) do
_,_,stats[v] = get_stat(v)
end
end
luci.http.status(200, "OK")
luci.http.prepare_content("application/json")
luci.http.write_json(stats)
end
function action_confirm()
local data = docker:read_status()

View File

@ -1,5 +1,8 @@
-- Copyright 2021 Florian Eckert <fe@dev.tdt.de>
-- Licensed to the public under the Apache License 2.0.
--[[
LuCI - Lua Configuration Interface
Copyright 2021 Florian Eckert <fe@dev.tdt.de>
Copyright 2021 lisaac <lisaac.cn@gmail.com>
]]--
local uci = (require "luci.model.uci").cursor()
@ -14,7 +17,6 @@ if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "docker
o = s:option(Flag, "auto_start", translate("Auto start"))
o.rmempty = false
o.default = "no"
o.write = function(self, section, value)
if value == "1" then
luci.util.exec("/etc/init.d/dockerd enable")
@ -119,9 +121,22 @@ if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "docker
o:value(v, v)
end
o = s:taboption("ac", DynamicList, "ac_allowed_container", translate("Containers allowed to be accessed"), translate("Which container(s) under bridge network can be accessed, even from interfaces that are not allowed, fill-in Container Id or Name"))
local docker = require "luci.model.docker"
local containers, res, lost_state
local dk = docker.new()
if dk:_ping().code ~= 200 then
lost_state = true
else
lost_state = false
res = dk.containers:list()
if res and res.code and res.code < 300 then
containers = res.body
end
end
-- allowed_container.placeholder = "container name_or_id"
if containers_list then
for i, v in ipairs(containers_list) do
if containers then
for i, v in ipairs(containers) do
if v.State == "running" and v.NetworkSettings and v.NetworkSettings.Networks and v.NetworkSettings.Networks.bridge and v.NetworkSettings.Networks.bridge.IPAddress then
o:value(v.Id:sub(1,12), v.Names[1]:sub(2) .. " | " .. v.NetworkSettings.Networks.bridge.IPAddress)
end

View File

@ -392,7 +392,7 @@ if action == "info" then
for k,v in pairs(info_networks) do
table_info["14network"..k] = {
_key = translate("Network"),
value = k.. (v~="" and (" | ".. v) or ""),
_value = k.. (v~="" and (" | ".. v) or ""),
_button=translate("Disconnect")
}
list_networks[k]=nil

View File

@ -377,8 +377,6 @@ if cmd_line and cmd_line:match("^DOCKERCLI.+") then
elseif cmd_line and cmd_line:match("^duplicate/[^/]+$") then
local container_id = cmd_line:match("^duplicate/(.+)")
create_body = dk:containers_duplicate_config({id = container_id}) or {}
luci.util.perror(luci.jsonc.stringify(create_body))
if not create_body.HostConfig then
create_body.HostConfig = {}
end

View File

@ -215,16 +215,9 @@ local upgrade = function(self, request)
return {code = 305, body = {message = "Already up to date"}}
end
_docker:append_status("Container: " .. "Stop" .. " " .. container_name .. "...")
res = self.containers:stop({name = container_name})
if res and res.code and res.code < 305 then
_docker:append_status("done\n")
else
return res
end
_docker:append_status("Container: rename" .. " " .. container_name .. " to ".. container_name .. "_old ...")
res = self.containers:rename({name = container_name, query = { name = container_name .. "_old" }})
local t = os.date("%Y%m%d%H%M%S")
_docker:append_status("Container: rename" .. " " .. container_name .. " to ".. container_name .. "_old_".. t .. "...")
res = self.containers:rename({name = container_name, query = { name = container_name .. "_old_" ..t }})
if res and res.code and res.code < 300 then
_docker:append_status("done\n")
else
@ -253,6 +246,22 @@ local upgrade = function(self, request)
_docker:append_status("done\n")
end
_docker:append_status("Container: " .. "Stop" .. " " .. container_name .. "_old_".. t .. "...")
res = self.containers:stop({name = container_name .. "_old_" ..t })
if res and res.code and res.code < 305 then
_docker:append_status("done\n")
else
return res
end
_docker:append_status("Container: " .. "Start" .. " " .. container_name .. "...")
res = self.containers:start({name = container_name})
if res and res.code and res.code < 305 then
_docker:append_status("done\n")
else
return res
end
_docker:clear_status()
return res
end

View File

@ -20,7 +20,8 @@
document.getElementById("a-cbi-tab-container_" + item).href= path[0]+"/admin/services/docker/container/"+container_id+'/'+item
if (action === item) {
document.getElementById("cbi-tab-container_" + item).className="cbi-tab"
} else {
}
else {
document.getElementById("cbi-tab-container_" + item).className="cbi-tab-disabled"
}
})

View File

@ -13,6 +13,7 @@
let last_bw_tx = {}
let last_bw_rx = {}
let interval = 5
let containers = []
lines.forEach((item) => {
let containerId = item.id.match(/cbi-containers-.+_id_(.*)/)
if (!containerId) { return }
@ -40,7 +41,42 @@
}
})
})
// containers.push(containerId)
})
// XHR.post('<%=luci.dispatcher.build_url("admin/docker/containers_stats")%>', {
// containers: JSON.stringify(containers)
// }, (x, info) => {
// lines.forEach((item) => {
// if (!info) { return }
// let containerId = item.id.match(/cbi-containers-.+_id_(.*)/)
// if (!containerId) { return }
// containerId = containerId[1]
// if (!info[containerId]) { return }
// infoC = info[containerId]
// if (item.getElementsByClassName("container_not_running").length > 0) { return }
// item.childNodes.forEach((cell) => {
// if (cell && cell.attributes) {
// if (cell.getAttribute("data-name") == "_status" || cell.childNodes[1] && cell.childNodes[1].id.match(/_status/)) {
// let runningStats = cell.getElementsByClassName("container_cpu_status")
// runningStats[0].innerText = "CPU: " + infoC.cpu_percent + "%"
// runningStats = cell.getElementsByClassName("container_mem_status")
// runningStats[0].innerText = "MEM: " + niceBytes(infoC.memory.mem_useage)
// runningStats = cell.getElementsByClassName("container_network_status")
// for (var eth in infoC.bw_rxtx) {
// if (last_bw_tx[containerId] != undefined && last_bw_rx[containerId] != undefined) {
// runningStats[0].innerText = '↑' + niceBytes((infoC.bw_rxtx[eth].bw_tx - last_bw_tx[containerId]) / interval) + '/s ↓' + niceBytes((infoC.bw_rxtx[eth].bw_rx - last_bw_rx[containerId]) / interval) + '/s'
// }
// last_bw_rx[containerId] = infoC.bw_rxtx[eth].bw_rx
// last_bw_tx[containerId] = infoC.bw_rxtx[eth].bw_tx
// }
// }
// }
// })
// })
// })
XHR.run()
XHR.halt()
}

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,16 @@
#!/bin/sh /etc/rc.common
START=99
config_load dockerd
USE_PROCD=1
# PROCD_DEBUG=1
config_load 'dockerd'
# config_get daemon_ea "dockerman" daemon_ea
docker_running(){
docker version > /dev/null 2>&1
return $?
}
init_dockerman_chain(){
iptables -N DOCKER-MAN >/dev/null 2>&1
iptables -F DOCKER-MAN >/dev/null 2>&1
@ -12,27 +18,57 @@ init_dockerman_chain(){
iptables -I DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1
}
delete_dockerman_chain(){
iptables -D DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1
iptables -F DOCKER-MAN >/dev/null 2>&1
iptables -X DOCKER-MAN >/dev/null 2>&1
}
add_allowed_interface(){
iptables -A DOCKER-MAN -i $1 -o docker0 -j RETURN
}
add_allowed_ip(){
iptables -A DOCKER-MAN -d $1 -o docker0 -j ACCEPT
add_allowed_container(){
ip=$(docker inspect --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ${1} 2>/dev/null)
[ -n "$ip" ] && iptables -A DOCKER-MAN -d $ip -o docker0 -j ACCEPT
}
handle_allowed_container(){
config_list_foreach "dockerman" "ac_allowed_container" add_allowed_container
}
handle_allowed_interface(){
#config_list_foreach "dockerman" allowed_ip add_allowed_ip
config_list_foreach "dockerman" ac_allowed_interface add_allowed_interface
config_list_foreach "dockerman" "ac_allowed_interface" add_allowed_interface
iptables -A DOCKER-MAN -m conntrack --ctstate ESTABLISHED,RELATED -o docker0 -j RETURN >/dev/null 2>&1
iptables -A DOCKER-MAN -m conntrack --ctstate NEW,INVALID -o docker0 -j DROP >/dev/null 2>&1
iptables -A DOCKER-MAN -j RETURN >/dev/null 2>&1
}
start(){
[ ! -x "/etc/init.d/dockerd" ] && return 0
start_service(){
_DOCKERD=/etc/init.d/dockerd
[ -x "$_DOCKERD" ] && $($_DOCKERD enabled) || return 0
delete_dockerman_chain
$($_DOCKERD running) && docker_running || return 0
init_dockerman_chain
# if [ -n "$daemon_ea" ]; then
# handle_allowed_container
handle_allowed_interface
lua /usr/share/dockerman/dockerd-ac.lua
# fi
}
stop_service(){
delete_dockerman_chain
}
service_triggers() {
procd_add_reload_trigger 'dockerd'
}
reload_service() {
start
}
boot() {
sleep 5s
start
}

View File

@ -1,20 +1,33 @@
#!/usr/bin/env lua
require "luci.util"
docker = require "luci.docker"
uci = (require "luci.model.uci").cursor()
dk = docker.new({socket_path = "/var/run/docker.sock"})
if dk:_ping().code ~= 200 then return end
containers_list = dk.containers:list({query = {all=true}}).body
allowed_container = uci:get("dockerd", "dockerman", "ac_allowed_container")
if not allowed_container or next(allowed_container)==nil then return end
allowed_ip = {}
for i, v in ipairs(containers_list) do
for ii, vv in ipairs(allowed_container) do
if v.Id:sub(1,12) == vv and v.NetworkSettings and v.NetworkSettings.Networks and v.NetworkSettings.Networks.bridge and v.NetworkSettings.Networks.bridge.IPAddress then
print(v.NetworkSettings.Networks.bridge.IPAddress)
luci.util.exec("iptables -I DOCKER-MAN -d "..v.NetworkSettings.Networks.bridge.IPAddress.." -o docker0 -j ACCEPT")
table.remove(allowed_container, ii)
end
end
if dk:_ping().code ~= 200 then
return
end
allowed_container = uci:get("dockerd", "dockerman", "ac_allowed_container")
if not allowed_container or next(allowed_container)==nil then
return
end
-- for i,v in ipairs(allowed_container) do
-- print(v)
-- end
containers_list = dk.containers:list({
query={
filters={
id=allowed_container
}
}
}).body
-- allowed_ip = {}
for i, v in ipairs(containers_list) do
if v.NetworkSettings and v.NetworkSettings.Networks and v.NetworkSettings.Networks.bridge and v.NetworkSettings.Networks.bridge.IPAddress and v.NetworkSettings.Networks.bridge.IPAddress ~= "" then
-- print(v.NetworkSettings.Networks.bridge.IPAddress)
luci.util.exec("iptables -I DOCKER-MAN -d "..v.NetworkSettings.Networks.bridge.IPAddress.." -o docker0 -j ACCEPT")
end
end

View File

@ -2,10 +2,10 @@
"luci-app-dockerman": {
"description": "Grant UCI access for luci-app-dockerman",
"read": {
"uci": [ "dockerman" ]
"uci": [ "dockerd" ]
},
"write": {
"uci": [ "dockerman" ]
"uci": [ "dockerd" ]
}
}
}