luci-lib-docker: update conding style
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
This commit is contained in:
parent
edb53058d0
commit
a722abd279
1 changed files with 425 additions and 341 deletions
|
@ -2,6 +2,7 @@
|
||||||
LuCI - Lua Configuration Interface
|
LuCI - Lua Configuration Interface
|
||||||
Copyright 2019 lisaac <https://github.com/lisaac/luci-lib-docker>
|
Copyright 2019 lisaac <https://github.com/lisaac/luci-lib-docker>
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
require "nixio.util"
|
require "nixio.util"
|
||||||
require "luci.util"
|
require "luci.util"
|
||||||
local jsonc = require "luci.jsonc"
|
local jsonc = require "luci.jsonc"
|
||||||
|
@ -14,301 +15,376 @@ local json_stringify = jsonc.stringify
|
||||||
local json_parse = jsonc.parse
|
local json_parse = jsonc.parse
|
||||||
|
|
||||||
local chunksource = function(sock, buffer)
|
local chunksource = function(sock, buffer)
|
||||||
buffer = buffer or ""
|
buffer = buffer or ""
|
||||||
return function()
|
|
||||||
local output
|
return function()
|
||||||
local _, endp, count = buffer:find("^([0-9a-fA-F]+)\r\n")
|
local output
|
||||||
if not count then
|
local _, endp, count = buffer:find("^([0-9a-fA-F]+)\r\n")
|
||||||
local newblock, code = sock:recv(1024)
|
|
||||||
if not newblock then return nil, code end
|
if not count then
|
||||||
buffer = buffer .. newblock
|
local newblock, code = sock:recv(1024)
|
||||||
_, endp, count = buffer:find("^([0-9a-fA-F]+)\r\n")
|
if not newblock then
|
||||||
end
|
return nil, code
|
||||||
count = tonumber(count, 16)
|
end
|
||||||
if not count then
|
buffer = buffer .. newblock
|
||||||
return nil, -1, "invalid encoding"
|
_, endp, count = buffer:find("^([0-9a-fA-F]+)\r\n")
|
||||||
elseif count == 0 then -- finial
|
end
|
||||||
return nil
|
|
||||||
elseif count <= #buffer - endp then
|
count = tonumber(count, 16)
|
||||||
--data >= count
|
if not count then
|
||||||
output = buffer:sub(endp + 1, endp + count)
|
return nil, -1, "invalid encoding"
|
||||||
if count == #buffer - endp then -- [data]
|
elseif count == 0 then -- finial
|
||||||
buffer = buffer:sub(endp + count + 1)
|
return nil
|
||||||
count, code = sock:recvall(2) --read \r\n
|
elseif count <= #buffer - endp then -- data >= count
|
||||||
if not count then return nil, code end
|
output = buffer:sub(endp + 1, endp + count)
|
||||||
elseif count + 1 == #buffer - endp then -- [data]\r
|
if count == #buffer - endp then -- [data]
|
||||||
buffer = buffer:sub(endp + count + 2)
|
buffer = buffer:sub(endp + count + 1)
|
||||||
count, code = sock:recvall(1) --read \n
|
count, code = sock:recvall(2) --read \r\n
|
||||||
if not count then return nil, code end
|
if not count then
|
||||||
else -- [data]\r\n[count]\r\n[data]...
|
return nil, code
|
||||||
buffer = buffer:sub(endp + count + 3) -- cut buffer
|
end
|
||||||
end
|
elseif count + 1 == #buffer - endp then -- [data]\r
|
||||||
return output
|
buffer = buffer:sub(endp + count + 2)
|
||||||
else
|
count, code = sock:recvall(1) --read \n
|
||||||
-- data < count
|
if not count then
|
||||||
output = buffer:sub(endp + 1, endp + count)
|
return nil, code
|
||||||
buffer = buffer:sub(endp + count + 1)
|
end
|
||||||
local remain, code = sock:recvall(count - #output) --need read remaining
|
else -- [data]\r\n[count]\r\n[data]...
|
||||||
if not remain then return nil, code end
|
buffer = buffer:sub(endp + count + 3) -- cut buffer
|
||||||
output = output .. remain
|
end
|
||||||
count, code = sock:recvall(2) --read \r\n
|
return output
|
||||||
if not count then return nil, code end
|
else -- data < count
|
||||||
return output
|
output = buffer:sub(endp + 1, endp + count)
|
||||||
end
|
buffer = buffer:sub(endp + count + 1)
|
||||||
end
|
local remain, code = sock:recvall(count - #output) --need read remaining
|
||||||
|
if not remain then
|
||||||
|
return nil, code
|
||||||
|
end
|
||||||
|
output = output .. remain
|
||||||
|
count, code = sock:recvall(2) --read \r\n
|
||||||
|
if not count then
|
||||||
|
return nil, code
|
||||||
|
end
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local chunksink = function (sock)
|
local chunksink = function (sock)
|
||||||
return function(chunk, err)
|
return function(chunk, err)
|
||||||
if not chunk then
|
if not chunk then
|
||||||
return sock:writeall("0\r\n\r\n")
|
return sock:writeall("0\r\n\r\n")
|
||||||
else
|
else
|
||||||
return sock:writeall(("%X\r\n%s\r\n"):format(#chunk, tostring(chunk)))
|
return sock:writeall(("%X\r\n%s\r\n"):format(#chunk, tostring(chunk)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local docker_stream_filter = function(buffer)
|
local docker_stream_filter = function(buffer)
|
||||||
buffer = buffer or ""
|
buffer = buffer or ""
|
||||||
if #buffer < 8 then
|
if #buffer < 8 then
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
local stream_type = ((string.byte(buffer, 1) == 1) and "stdout") or ((string.byte(buffer, 1) == 2) and "stderr") or ((string.byte(buffer, 1) == 0) and "stdin") or "stream_err"
|
local stream_type = ((string.byte(buffer, 1) == 1) and "stdout") or ((string.byte(buffer, 1) == 2) and "stderr") or ((string.byte(buffer, 1) == 0) and "stdin") or "stream_err"
|
||||||
local valid_length =
|
local valid_length = tonumber(string.byte(buffer, 5)) * 256 * 256 * 256 + tonumber(string.byte(buffer, 6)) * 256 * 256 + tonumber(string.byte(buffer, 7)) * 256 + tonumber(string.byte(buffer, 8))
|
||||||
tonumber(string.byte(buffer, 5)) * 256 * 256 * 256 + tonumber(string.byte(buffer, 6)) * 256 * 256 + tonumber(string.byte(buffer, 7)) * 256 + tonumber(string.byte(buffer, 8))
|
if valid_length > #buffer + 8 then
|
||||||
if valid_length > #buffer + 8 then
|
return ""
|
||||||
return ""
|
end
|
||||||
end
|
return stream_type .. ": " .. string.sub(buffer, 9, valid_length + 8)
|
||||||
return stream_type .. ": " .. string.sub(buffer, 9, valid_length + 8)
|
|
||||||
-- return string.sub(buffer, 9, valid_length + 8)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local open_socket = function(req_options)
|
local open_socket = function(req_options)
|
||||||
local socket
|
local socket
|
||||||
if type(req_options) ~= "table" then return socket end
|
if type(req_options) ~= "table" then
|
||||||
if req_options.socket_path then
|
return socket
|
||||||
socket = nixio.socket("unix", "stream")
|
end
|
||||||
if socket:connect(req_options.socket_path) ~= true then return nil end
|
if req_options.socket_path then
|
||||||
elseif req_options.host and req_options.port then
|
socket = nixio.socket("unix", "stream")
|
||||||
socket = nixio.connect(req_options.host, req_options.port)
|
if socket:connect(req_options.socket_path) ~= true then
|
||||||
end
|
return nil
|
||||||
if socket then
|
end
|
||||||
return socket
|
elseif req_options.host and req_options.port then
|
||||||
else
|
socket = nixio.connect(req_options.host, req_options.port)
|
||||||
return nil
|
end
|
||||||
end
|
if socket then
|
||||||
|
return socket
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local send_http_socket = function(docker_socket, req_header, req_body, callback)
|
local send_http_socket = function(docker_socket, req_header, req_body, callback)
|
||||||
if docker_socket:send(req_header) == 0 then
|
if docker_socket:send(req_header) == 0 then
|
||||||
return {
|
return {
|
||||||
headers={code=498,message="bad path", protocol="HTTP/1.1"},
|
headers={
|
||||||
body={message="can\'t send data to socket"}
|
code=498,
|
||||||
}
|
message="bad path",
|
||||||
end
|
protocol="HTTP/1.1"
|
||||||
|
},
|
||||||
|
body={
|
||||||
|
message="can\'t send data to socket"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
if req_body and type(req_body) == "function" and req_header and req_header:match("chunked") then
|
if req_body and type(req_body) == "function" and req_header and req_header:match("chunked") then
|
||||||
-- chunked send
|
-- chunked send
|
||||||
req_body(chunksink(docker_socket))
|
req_body(chunksink(docker_socket))
|
||||||
elseif req_body and type(req_body) == "function" then
|
elseif req_body and type(req_body) == "function" then
|
||||||
-- normal send by req_body function
|
-- normal send by req_body function
|
||||||
req_body(docker_socket)
|
req_body(docker_socket)
|
||||||
elseif req_body and type(req_body) == "table" then
|
elseif req_body and type(req_body) == "table" then
|
||||||
-- json
|
-- json
|
||||||
docker_socket:send(json_stringify(req_body))
|
docker_socket:send(json_stringify(req_body))
|
||||||
if options.debug then io.popen("echo '".. json_stringify(req_body) .. "' >> " .. options.debug_path) end
|
if options.debug then
|
||||||
elseif req_body then
|
io.popen("echo '".. json_stringify(req_body) .. "' >> " .. options.debug_path)
|
||||||
docker_socket:send(req_body)
|
end
|
||||||
if options.debug then io.popen("echo '".. req_body .. "' >> " .. options.debug_path) end
|
elseif req_body then
|
||||||
end
|
docker_socket:send(req_body)
|
||||||
|
if options.debug then
|
||||||
|
io.popen("echo '".. req_body .. "' >> " .. options.debug_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local linesrc = docker_socket:linesource()
|
local linesrc = docker_socket:linesource()
|
||||||
-- read socket using source http://w3.impa.br/~diego/software/luasocket/ltn12.html
|
-- read socket using source http://w3.impa.br/~diego/software/luasocket/ltn12.html
|
||||||
--http://lua-users.org/wiki/FiltersSourcesAndSinks
|
-- http://lua-users.org/wiki/FiltersSourcesAndSinks
|
||||||
-- handle response header
|
-- handle response header
|
||||||
local line = linesrc()
|
local line = linesrc()
|
||||||
if not line then
|
if not line then
|
||||||
docker_socket:close()
|
docker_socket:close()
|
||||||
return {
|
return {
|
||||||
headers = {code=499, message="bad socket path", protocol="HTTP/1.1"},
|
headers = {
|
||||||
body = {message="no data receive from socket"}
|
code=499,
|
||||||
}
|
message="bad socket path",
|
||||||
end
|
protocol="HTTP/1.1"
|
||||||
local response = {code = 0, headers = {}, body = {}}
|
},
|
||||||
|
body = {
|
||||||
|
message="no data receive from socket"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local p, code, msg = line:match("^([%w./]+) ([0-9]+) (.*)")
|
local response = {
|
||||||
response.protocol = p
|
code = 0,
|
||||||
response.code = tonumber(code)
|
headers = {},
|
||||||
response.message = msg
|
body = {}
|
||||||
line = linesrc()
|
}
|
||||||
while line and line ~= "" do
|
|
||||||
local key, val = line:match("^([%w-]+)%s?:%s?(.*)")
|
local p, code, msg = line:match("^([%w./]+) ([0-9]+) (.*)")
|
||||||
if key and key ~= "Status" then
|
response.protocol = p
|
||||||
if type(response.headers[key]) == "string" then
|
response.code = tonumber(code)
|
||||||
response.headers[key] = {response.headers[key], val}
|
response.message = msg
|
||||||
elseif type(response.headers[key]) == "table" then
|
line = linesrc()
|
||||||
response.headers[key][#response.headers[key] + 1] = val
|
|
||||||
else
|
while line and line ~= "" do
|
||||||
response.headers[key] = val
|
local key, val = line:match("^([%w-]+)%s?:%s?(.*)")
|
||||||
end
|
if key and key ~= "Status" then
|
||||||
end
|
if type(response.headers[key]) == "string" then
|
||||||
line = linesrc()
|
response.headers[key] = {
|
||||||
end
|
response.headers[key],
|
||||||
-- handle response body
|
val
|
||||||
local body_buffer = linesrc(true)
|
}
|
||||||
response.body = {}
|
elseif type(response.headers[key]) == "table" then
|
||||||
if type(callback) ~= "function" then
|
response.headers[key][#response.headers[key] + 1] = val
|
||||||
if response.headers["Transfer-Encoding"] == "chunked" then
|
else
|
||||||
local source = chunksource(docker_socket, body_buffer)
|
response.headers[key] = val
|
||||||
code = ltn12.pump.all(source, (ltn12.sink.table(response.body))) and response.code or 555
|
end
|
||||||
response.code = code
|
end
|
||||||
else
|
line = linesrc()
|
||||||
local body_source = ltn12.source.cat(ltn12.source.string(body_buffer), docker_socket:blocksource())
|
end
|
||||||
code = ltn12.pump.all(body_source, (ltn12.sink.table(response.body))) and response.code or 555
|
|
||||||
response.code = code
|
-- handle response body
|
||||||
end
|
local body_buffer = linesrc(true)
|
||||||
else
|
response.body = {}
|
||||||
if response.headers["Transfer-Encoding"] == "chunked" then
|
|
||||||
local source = chunksource(docker_socket, body_buffer)
|
if type(callback) ~= "function" then
|
||||||
callback(response, source)
|
if response.headers["Transfer-Encoding"] == "chunked" then
|
||||||
else
|
local source = chunksource(docker_socket, body_buffer)
|
||||||
local body_source = ltn12.source.cat(ltn12.source.string(body_buffer), docker_socket:blocksource())
|
code = ltn12.pump.all(source, (ltn12.sink.table(response.body))) and response.code or 555
|
||||||
callback(response, body_source)
|
response.code = code
|
||||||
end
|
else
|
||||||
end
|
local body_source = ltn12.source.cat(ltn12.source.string(body_buffer), docker_socket:blocksource())
|
||||||
docker_socket:close()
|
code = ltn12.pump.all(body_source, (ltn12.sink.table(response.body))) and response.code or 555
|
||||||
return response
|
response.code = code
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if response.headers["Transfer-Encoding"] == "chunked" then
|
||||||
|
local source = chunksource(docker_socket, body_buffer)
|
||||||
|
callback(response, source)
|
||||||
|
else
|
||||||
|
local body_source = ltn12.source.cat(ltn12.source.string(body_buffer), docker_socket:blocksource())
|
||||||
|
callback(response, body_source)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
docker_socket:close()
|
||||||
|
return response
|
||||||
end
|
end
|
||||||
|
|
||||||
local gen_header = function(options, http_method, api_group, api_action, name_or_id, request)
|
local gen_header = function(options, http_method, api_group, api_action, name_or_id, request)
|
||||||
local header, query, path
|
local header, query, path
|
||||||
name_or_id = (name_or_id ~= "") and name_or_id or nil
|
name_or_id = (name_or_id ~= "") and name_or_id or nil
|
||||||
|
|
||||||
if request and type(request.query) == "table" then
|
if request and type(request.query) == "table" then
|
||||||
local k, v
|
local k, v
|
||||||
for k, v in pairs(request.query) do
|
for k, v in pairs(request.query) do
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
query = (query and query .. "&" or "?") .. k .. "=" .. urlencode(json_stringify(v))
|
query = (query and query .. "&" or "?") .. k .. "=" .. urlencode(json_stringify(v))
|
||||||
elseif type(v) == "boolean" then
|
elseif type(v) == "boolean" then
|
||||||
query = (query and query .. "&" or "?") .. k .. "=" .. (v and "true" or "false")
|
query = (query and query .. "&" or "?") .. k .. "=" .. (v and "true" or "false")
|
||||||
elseif type(v) == "number" or type(v) == "string" then
|
elseif type(v) == "number" or type(v) == "string" then
|
||||||
query = (query and query .. "&" or "?") .. k .. "=" .. v
|
query = (query and query .. "&" or "?") .. k .. "=" .. v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
path = (api_group and ("/" .. api_group) or "") .. (name_or_id and ("/" .. name_or_id) or "") .. (api_action and ("/" .. api_action) or "") .. (query or "")
|
|
||||||
header = (http_method or "GET") .. " " .. path .. " " .. options.protocol .. "\r\n"
|
|
||||||
header = header .. "Host: " .. options.host .. "\r\n"
|
|
||||||
header = header .. "User-Agent: " .. options.user_agent .. "\r\n"
|
|
||||||
header = header .. "Connection: close\r\n"
|
|
||||||
|
|
||||||
if request and type(request.header) == "table" then
|
path = (api_group and ("/" .. api_group) or "") .. (name_or_id and ("/" .. name_or_id) or "") .. (api_action and ("/" .. api_action) or "") .. (query or "")
|
||||||
local k, v
|
header = (http_method or "GET") .. " " .. path .. " " .. options.protocol .. "\r\n"
|
||||||
for k, v in pairs(request.header) do
|
header = header .. "Host: " .. options.host .. "\r\n"
|
||||||
header = header .. k .. ": " .. v .. "\r\n"
|
header = header .. "User-Agent: " .. options.user_agent .. "\r\n"
|
||||||
end
|
header = header .. "Connection: close\r\n"
|
||||||
end
|
|
||||||
|
|
||||||
-- when requst_body is function, we need to custom header using custom header
|
if request and type(request.header) == "table" then
|
||||||
if request and request.body and type(request.body) == "function" then
|
local k, v
|
||||||
if not header:match("Content-Length:") then
|
for k, v in pairs(request.header) do
|
||||||
header = header .. "Transfer-Encoding: chunked\r\n"
|
header = header .. k .. ": " .. v .. "\r\n"
|
||||||
end
|
end
|
||||||
elseif http_method == "POST" and request and request.body and type(request.body) == "table" then
|
end
|
||||||
local conetnt_json = json_stringify(request.body)
|
|
||||||
header = header .. "Content-Type: application/json\r\n"
|
-- when requst_body is function, we need to custom header using custom header
|
||||||
header = header .. "Content-Length: " .. #conetnt_json .. "\r\n"
|
if request and request.body and type(request.body) == "function" then
|
||||||
elseif request and request.body and type(request.body) == "string" then
|
if not header:match("Content-Length:") then
|
||||||
header = header .. "Content-Length: " .. #request.body .. "\r\n"
|
header = header .. "Transfer-Encoding: chunked\r\n"
|
||||||
end
|
end
|
||||||
header = header .. "\r\n"
|
elseif http_method == "POST" and request and request.body and type(request.body) == "table" then
|
||||||
if options.debug then io.popen("echo '".. header .. "' >> " .. options.debug_path) end
|
local conetnt_json = json_stringify(request.body)
|
||||||
return header
|
header = header .. "Content-Type: application/json\r\n"
|
||||||
|
header = header .. "Content-Length: " .. #conetnt_json .. "\r\n"
|
||||||
|
elseif request and request.body and type(request.body) == "string" then
|
||||||
|
header = header .. "Content-Length: " .. #request.body .. "\r\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
header = header .. "\r\n"
|
||||||
|
if options.debug then
|
||||||
|
io.popen("echo '".. header .. "' >> " .. options.debug_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
return header
|
||||||
end
|
end
|
||||||
|
|
||||||
local call_docker = function(options, http_method, api_group, api_action, name_or_id, request, callback)
|
local call_docker = function(options, http_method, api_group, api_action, name_or_id, request, callback)
|
||||||
local req_options = setmetatable({}, {__index = options})
|
local req_options = setmetatable({}, {
|
||||||
|
__index = options
|
||||||
|
})
|
||||||
|
|
||||||
local req_header = gen_header(req_options, http_method, api_group, api_action, name_or_id, request)
|
local req_header = gen_header(req_options,
|
||||||
local req_body = request and request.body or nil
|
http_method,
|
||||||
local docker_socket = open_socket(req_options)
|
api_group,
|
||||||
|
api_action,
|
||||||
|
name_or_id,
|
||||||
|
request)
|
||||||
|
|
||||||
if docker_socket then
|
local req_body = request and request.body or nil
|
||||||
return send_http_socket(docker_socket, req_header, req_body, callback)
|
local docker_socket = open_socket(req_options)
|
||||||
else
|
|
||||||
return {
|
if docker_socket then
|
||||||
headers = {code=497, message="bad socket path or host", protocol="HTTP/1.1"},
|
return send_http_socket(docker_socket, req_header, req_body, callback)
|
||||||
body = {message="can\'t connect to socket"}
|
else
|
||||||
}
|
return {
|
||||||
end
|
headers = {
|
||||||
|
code=497,
|
||||||
|
message="bad socket path or host",
|
||||||
|
protocol="HTTP/1.1"
|
||||||
|
},
|
||||||
|
body = {
|
||||||
|
message="can\'t connect to socket"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local gen_api = function(_table, http_method, api_group, api_action)
|
local gen_api = function(_table, http_method, api_group, api_action)
|
||||||
local _api_action
|
local _api_action
|
||||||
if api_action == "get_archive" or api_action == "put_archive" then
|
|
||||||
_api_action = "archive"
|
|
||||||
elseif api_action == "df" then
|
|
||||||
_api_action = "system/df"
|
|
||||||
elseif api_action ~= "list" and api_action ~= "inspect" and api_action ~= "remove" then
|
|
||||||
_api_action = api_action
|
|
||||||
elseif (api_group == "containers" or api_group == "images" or api_group == "exec") and (api_action == "list" or api_action == "inspect") then
|
|
||||||
_api_action = "json"
|
|
||||||
end
|
|
||||||
|
|
||||||
local fp = function(self, request, callback)
|
if api_action == "get_archive" or api_action == "put_archive" then
|
||||||
local name_or_id = request and (request.name or request.id or request.name_or_id) or nil
|
api_action = "archive"
|
||||||
if api_action == "list" then
|
elseif api_action == "df" then
|
||||||
if (name_or_id ~= "" and name_or_id ~= nil) then
|
_api_action = "system/df"
|
||||||
if api_group == "images" then
|
elseif api_action ~= "list" and api_action ~= "inspect" and api_action ~= "remove" then
|
||||||
name_or_id = nil
|
_api_action = api_action
|
||||||
else
|
elseif (api_group == "containers" or api_group == "images" or api_group == "exec") and (api_action == "list" or api_action == "inspect") then
|
||||||
request.query = request and request.query or {}
|
_api_action = "json"
|
||||||
request.query.filters = request.query.filters or {}
|
end
|
||||||
request.query.filters.name = request.query.filters.name or {}
|
|
||||||
request.query.filters.name[#request.query.filters.name + 1] = name_or_id
|
|
||||||
name_or_id = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif api_action == "create" then
|
|
||||||
if (name_or_id ~= "" and name_or_id ~= nil) then
|
|
||||||
request.query = request and request.query or {}
|
|
||||||
request.query.name = request.query.name or name_or_id
|
|
||||||
name_or_id = nil
|
|
||||||
end
|
|
||||||
elseif api_action == "logs" then
|
|
||||||
local body_buffer = ""
|
|
||||||
local response = call_docker(self.options, http_method, api_group, _api_action, name_or_id, request, callback)
|
|
||||||
if response.code >= 200 and response.code < 300 then
|
|
||||||
for i, v in ipairs(response.body) do
|
|
||||||
body_buffer = body_buffer .. docker_stream_filter(response.body[i])
|
|
||||||
end
|
|
||||||
response.body = body_buffer
|
|
||||||
end
|
|
||||||
return response
|
|
||||||
end
|
|
||||||
local response = call_docker(self.options, http_method, api_group, _api_action, name_or_id, request, callback)
|
|
||||||
if response.headers and response.headers["Content-Type"] == "application/json" then
|
|
||||||
if #response.body == 1 then
|
|
||||||
response.body = json_parse(response.body[1])
|
|
||||||
else
|
|
||||||
local tmp = {}
|
|
||||||
for _, v in ipairs(response.body) do
|
|
||||||
tmp[#tmp+1] = json_parse(v)
|
|
||||||
end
|
|
||||||
response.body = tmp
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return response
|
|
||||||
end
|
|
||||||
|
|
||||||
if api_group then
|
local fp = function(self, request, callback)
|
||||||
_table[api_group][api_action] = fp
|
local name_or_id = request and (request.name or request.id or request.name_or_id) or nil
|
||||||
else
|
|
||||||
_table[api_action] = fp
|
if api_action == "list" then
|
||||||
end
|
if (name_or_id ~= "" and name_or_id ~= nil) then
|
||||||
|
if api_group == "images" then
|
||||||
|
name_or_id = nil
|
||||||
|
else
|
||||||
|
request.query = request and request.query or {}
|
||||||
|
request.query.filters = request.query.filters or {}
|
||||||
|
request.query.filters.name = request.query.filters.name or {}
|
||||||
|
request.query.filters.name[#request.query.filters.name + 1] = name_or_id
|
||||||
|
name_or_id = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif api_action == "create" then
|
||||||
|
if (name_or_id ~= "" and name_or_id ~= nil) then
|
||||||
|
request.query = request and request.query or {}
|
||||||
|
request.query.name = request.query.name or name_or_id
|
||||||
|
name_or_id = nil
|
||||||
|
end
|
||||||
|
elseif api_action == "logs" then
|
||||||
|
local body_buffer = ""
|
||||||
|
local response = call_docker(self.options,
|
||||||
|
http_method,
|
||||||
|
api_group,
|
||||||
|
_api_action,
|
||||||
|
name_or_id,
|
||||||
|
request,
|
||||||
|
callback)
|
||||||
|
if response.code >= 200 and response.code < 300 then
|
||||||
|
for i, v in ipairs(response.body) do
|
||||||
|
body_buffer = body_buffer .. docker_stream_filter(response.body[i])
|
||||||
|
end
|
||||||
|
response.body = body_buffer
|
||||||
|
end
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
local response = call_docker(self.options, http_method, api_group, _api_action, name_or_id, request, callback)
|
||||||
|
|
||||||
|
if response.headers and response.headers["Content-Type"] == "application/json" then
|
||||||
|
if #response.body == 1 then
|
||||||
|
response.body = json_parse(response.body[1])
|
||||||
|
else
|
||||||
|
local tmp = {}
|
||||||
|
for _, v in ipairs(response.body) do
|
||||||
|
tmp[#tmp+1] = json_parse(v)
|
||||||
|
end
|
||||||
|
response.body = tmp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
if api_group then
|
||||||
|
_table[api_group][api_action] = fp
|
||||||
|
else
|
||||||
|
_table[api_action] = fp
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local _docker = {containers = {}, exec = {}, images = {}, networks = {}, volumes = {}}
|
local _docker = {
|
||||||
|
containers = {},
|
||||||
|
exec = {},
|
||||||
|
images = {},
|
||||||
|
networks = {},
|
||||||
|
volumes = {}
|
||||||
|
}
|
||||||
|
|
||||||
gen_api(_docker, "GET", "containers", "list")
|
gen_api(_docker, "GET", "containers", "list")
|
||||||
gen_api(_docker, "POST", "containers", "create")
|
gen_api(_docker, "POST", "containers", "create")
|
||||||
|
@ -368,85 +444,93 @@ gen_api(_docker, "GET", nil, "_ping")
|
||||||
gen_api(_docker, "GET", nil, "df")
|
gen_api(_docker, "GET", nil, "df")
|
||||||
|
|
||||||
function _docker.new(options)
|
function _docker.new(options)
|
||||||
local docker = {}
|
local docker = {}
|
||||||
local _options = options or {}
|
local _options = options or {}
|
||||||
docker.options = {
|
|
||||||
socket_path = _options.socket_path or nil,
|
docker.options = {
|
||||||
host = _options.socket_path and "localhost" or _options.host,
|
socket_path = _options.socket_path or nil,
|
||||||
port = not _options.socket_path and _options.port or nil,
|
host = _options.socket_path and "localhost" or _options.host,
|
||||||
tls = _options.tls or nil,
|
port = not _options.socket_path and _options.port or nil,
|
||||||
tls_cacert = _options.tls and _options.tls_cacert or nil,
|
tls = _options.tls or nil,
|
||||||
tls_cert = _options.tls and _options.tls_cert or nil,
|
tls_cacert = _options.tls and _options.tls_cacert or nil,
|
||||||
tls_key = _options.tls and _options.tls_key or nil,
|
tls_cert = _options.tls and _options.tls_cert or nil,
|
||||||
version = _options.version or "v1.40",
|
tls_key = _options.tls and _options.tls_key or nil,
|
||||||
user_agent = _options.user_agent or "LuCI",
|
version = _options.version or "v1.40",
|
||||||
protocol = _options.protocol or "HTTP/1.1",
|
user_agent = _options.user_agent or "LuCI",
|
||||||
debug = _options.debug or false,
|
protocol = _options.protocol or "HTTP/1.1",
|
||||||
debug_path = _options.debug and _options.debug_path or nil
|
debug = _options.debug or false,
|
||||||
}
|
debug_path = _options.debug and _options.debug_path or nil
|
||||||
setmetatable(
|
}
|
||||||
docker,
|
|
||||||
{
|
setmetatable(
|
||||||
__index = function(t, key)
|
docker,
|
||||||
if _docker[key] ~= nil then
|
{
|
||||||
return _docker[key]
|
__index = function(t, key)
|
||||||
else
|
if _docker[key] ~= nil then
|
||||||
return _docker.containers[key]
|
return _docker[key]
|
||||||
end
|
else
|
||||||
end
|
return _docker.containers[key]
|
||||||
}
|
end
|
||||||
)
|
end
|
||||||
setmetatable(
|
}
|
||||||
docker.containers,
|
)
|
||||||
{
|
|
||||||
__index = function(t, key)
|
setmetatable(
|
||||||
if key == "options" then
|
docker.containers,
|
||||||
return docker.options
|
{
|
||||||
end
|
__index = function(t, key)
|
||||||
end
|
if key == "options" then
|
||||||
}
|
return docker.options
|
||||||
)
|
end
|
||||||
setmetatable(
|
end
|
||||||
docker.networks,
|
}
|
||||||
{
|
)
|
||||||
__index = function(t, key)
|
|
||||||
if key == "options" then
|
setmetatable(
|
||||||
return docker.options
|
docker.networks,
|
||||||
end
|
{
|
||||||
end
|
__index = function(t, key)
|
||||||
}
|
if key == "options" then
|
||||||
)
|
return docker.options
|
||||||
setmetatable(
|
end
|
||||||
docker.images,
|
end
|
||||||
{
|
}
|
||||||
__index = function(t, key)
|
)
|
||||||
if key == "options" then
|
|
||||||
return docker.options
|
setmetatable(
|
||||||
end
|
docker.images,
|
||||||
end
|
{
|
||||||
}
|
__index = function(t, key)
|
||||||
)
|
if key == "options" then
|
||||||
setmetatable(
|
return docker.options
|
||||||
docker.volumes,
|
end
|
||||||
{
|
end
|
||||||
__index = function(t, key)
|
}
|
||||||
if key == "options" then
|
)
|
||||||
return docker.options
|
|
||||||
end
|
setmetatable(
|
||||||
end
|
docker.volumes,
|
||||||
}
|
{
|
||||||
)
|
__index = function(t, key)
|
||||||
setmetatable(
|
if key == "options" then
|
||||||
docker.exec,
|
return docker.options
|
||||||
{
|
end
|
||||||
__index = function(t, key)
|
end
|
||||||
if key == "options" then
|
}
|
||||||
return docker.options
|
)
|
||||||
end
|
|
||||||
end
|
setmetatable(
|
||||||
}
|
docker.exec,
|
||||||
)
|
{
|
||||||
return docker
|
__index = function(t, key)
|
||||||
|
if key == "options" then
|
||||||
|
return docker.options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return docker
|
||||||
end
|
end
|
||||||
|
|
||||||
return _docker
|
return _docker
|
||||||
|
|
Loading…
Reference in a new issue