Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
]]--
-require "luci.util"
local docker = require "luci.docker"
local uci = (require "luci.model.uci").cursor()
--pull image and return iamge id
local update_image = function(self, image_name)
- local json_stringify = luci.jsonc and luci.jsonc.stringify
- _docker:append_status("Images: " .. "pulling" .. " " .. image_name .. "...\n")
- local res = self.images:create({query = {fromImage=image_name}}, _docker.pull_image_show_status_cb)
- if res and res.code == 200 and (#res.body > 0 and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. image_name)) then
- _docker:append_status("done\n")
- else
- res.body.message = res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)
- end
- new_image_id = self.images:inspect({name = image_name}).body.Id
- return new_image_id, res
+ local json_stringify = luci.jsonc and luci.jsonc.stringify
+ _docker:append_status("Images: " .. "pulling" .. " " .. image_name .. "...\n")
+ local res = self.images:create({query = {fromImage=image_name}}, _docker.pull_image_show_status_cb)
+
+ if res and res.code == 200 and (#res.body > 0 and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. image_name)) then
+ _docker:append_status("done\n")
+ else
+ res.body.message = res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)
+ end
+
+ new_image_id = self.images:inspect({name = image_name}).body.Id
+ return new_image_id, res
end
local table_equal = function(t1, t2)
- if not t1 then return true end
- if not t2 then return false end
- if #t1 ~= #t2 then return false end
- for i, v in ipairs(t1) do
- if t1[i] ~= t2[i] then return false end
- end
- return true
+ if not t1 then
+ return true
+ end
+
+ if not t2 then
+ return false
+ end
+
+ if #t1 ~= #t2 then
+ return false
+ end
+
+ for i, v in ipairs(t1) do
+ if t1[i] ~= t2[i] then
+ return false
+ end
+ end
+
+ return true
end
local table_subtract = function(t1, t2)
- if not t1 or next(t1) == nil then return nil end
- if not t2 or next(t2) == nil then return t1 end
- local res = {}
- for _, v1 in ipairs(t1) do
- local found = false
- for _, v2 in ipairs(t2) do
- if v1 == v2 then
- found= true
- break
- end
- end
- if not found then
- table.insert(res, v1)
- end
- end
- return next(res) == nil and nil or res
+ if not t1 or next(t1) == nil then
+ return nil
+ end
+
+ if not t2 or next(t2) == nil then
+ return t1
+ end
+
+ local res = {}
+ for _, v1 in ipairs(t1) do
+ local found = false
+ for _, v2 in ipairs(t2) do
+ if v1 == v2 then
+ found= true
+ break
+ end
+ end
+ if not found then
+ table.insert(res, v1)
+ end
+ end
+
+ return next(res) == nil and nil or res
end
local map_subtract = function(t1, t2)
- if not t1 or next(t1) == nil then return nil end
- if not t2 or next(t2) == nil then return t1 end
- local res = {}
- for k1, v1 in pairs(t1) do
- local found = false
- for k2, v2 in ipairs(t2) do
- if k1 == k2 and luci.util.serialize_data(v1) == luci.util.serialize_data(v2) then
- found= true
- break
- end
- end
- if not found then
- res[k1] = v1
- -- if v1 and type(v1) == "table" then
- -- if next(v1) == nil then
- -- res[k1] = { k = 'v' }
- -- else
- -- res[k1] = v1
- -- end
- -- end
- end
- end
-
- return next(res) ~= nil and res or nil
+ if not t1 or next(t1) == nil then
+ return nil
+ end
+
+ if not t2 or next(t2) == nil then
+ return t1
+ end
+
+ local res = {}
+ for k1, v1 in pairs(t1) do
+ local found = false
+ for k2, v2 in ipairs(t2) do
+ if k1 == k2 and luci.util.serialize_data(v1) == luci.util.serialize_data(v2) then
+ found= true
+ break
+ end
+ end
+
+ if not found then
+ res[k1] = v1
+ end
+ end
+
+ return next(res) ~= nil and res or nil
end
_docker.clear_empty_tables = function ( t )
- local k, v
- if next(t) == nil then
- t = nil
- else
- for k, v in pairs(t) do
- if type(v) == 'table' then
- t[k] = _docker.clear_empty_tables(v)
- end
- end
- end
- return t
+ local k, v
+
+ if next(t) == nil then
+ t = nil
+ else
+ for k, v in pairs(t) do
+ if type(v) == 'table' then
+ t[k] = _docker.clear_empty_tables(v)
+ end
+ end
+ end
+
+ return t
end
--- return create_body, extra_network
local get_config = function(container_config, image_config)
- local config = container_config.Config
- local old_host_config = container_config.HostConfig
- local old_network_setting = container_config.NetworkSettings.Networks or {}
- if config.WorkingDir == image_config.WorkingDir then config.WorkingDir = "" end
- if config.User == image_config.User then config.User = "" end
- if table_equal(config.Cmd, image_config.Cmd) then config.Cmd = nil end
- if table_equal(config.Entrypoint, image_config.Entrypoint) then config.Entrypoint = nil end
- if table_equal(config.ExposedPorts, image_config.ExposedPorts) then config.ExposedPorts = nil end
- config.Env = table_subtract(config.Env, image_config.Env)
- config.Labels = table_subtract(config.Labels, image_config.Labels)
- config.Volumes = map_subtract(config.Volumes, image_config.Volumes)
- -- subtract ports exposed in image from container
- if old_host_config.PortBindings and next(old_host_config.PortBindings) ~= nil then
- config.ExposedPorts = {}
- for p, v in pairs(old_host_config.PortBindings) do
- config.ExposedPorts[p] = { HostPort=v[1] and v[1].HostPort }
- end
- end
-
- -- handle network config, we need only one network, extras need to network connect action
- local network_setting = {}
- local multi_network = false
- local extra_network = {}
- for k, v in pairs(old_network_setting) do
- if multi_network then
- extra_network[k] = v
- else
- network_setting[k] = v
- end
- multi_network = true
- end
-
- -- handle hostconfig
- local host_config = old_host_config
- -- if host_config.PortBindings and next(host_config.PortBindings) == nil then host_config.PortBindings = nil end
- -- host_config.LogConfig = nil
- host_config.Mounts = {}
- -- for volumes
- for i, v in ipairs(container_config.Mounts) do
- if v.Type == "volume" then
- table.insert(host_config.Mounts, {
- Type = v.Type,
- Target = v.Destination,
- Source = v.Source:match("([^/]+)\/_data"),
- BindOptions = (v.Type == "bind") and {Propagation = v.Propagation} or nil,
- ReadOnly = not v.RW
- })
- end
- end
-
-
- -- merge configs
- local create_body = config
- create_body["HostConfig"] = host_config
- create_body["NetworkingConfig"] = {EndpointsConfig = network_setting}
- create_body = _docker.clear_empty_tables(create_body) or {}
- extra_network = _docker.clear_empty_tables(extra_network) or {}
- return create_body, extra_network
+ local config = container_config.Config
+ local old_host_config = container_config.HostConfig
+ local old_network_setting = container_config.NetworkSettings.Networks or {}
+
+ if config.WorkingDir == image_config.WorkingDir then
+ config.WorkingDir = ""
+ end
+
+ if config.User == image_config.User then
+ config.User = ""
+ end
+
+ if table_equal(config.Cmd, image_config.Cmd) then
+ config.Cmd = nil
+ end
+
+ if table_equal(config.Entrypoint, image_config.Entrypoint) then
+ config.Entrypoint = nil
+ end
+
+ if table_equal(config.ExposedPorts, image_config.ExposedPorts) then
+ config.ExposedPorts = nil
+ end
+
+ config.Env = table_subtract(config.Env, image_config.Env)
+ config.Labels = table_subtract(config.Labels, image_config.Labels)
+ config.Volumes = map_subtract(config.Volumes, image_config.Volumes)
+
+ if old_host_config.PortBindings and next(old_host_config.PortBindings) ~= nil then
+ config.ExposedPorts = {}
+ for p, v in pairs(old_host_config.PortBindings) do
+ config.ExposedPorts[p] = { HostPort=v[1] and v[1].HostPort }
+ end
+ end
+
+ local network_setting = {}
+ local multi_network = false
+ local extra_network = {}
+
+ for k, v in pairs(old_network_setting) do
+ if multi_network then
+ extra_network[k] = v
+ else
+ network_setting[k] = v
+ end
+ multi_network = true
+ end
+
+ local host_config = old_host_config
+ host_config.Mounts = {}
+ for i, v in ipairs(container_config.Mounts) do
+ if v.Type == "volume" then
+ table.insert(host_config.Mounts, {
+ Type = v.Type,
+ Target = v.Destination,
+ Source = v.Source:match("([^/]+)\/_data"),
+ BindOptions = (v.Type == "bind") and {Propagation = v.Propagation} or nil,
+ ReadOnly = not v.RW
+ })
+ end
+ end
+
+ local create_body = config
+ create_body["HostConfig"] = host_config
+ create_body["NetworkingConfig"] = {EndpointsConfig = network_setting}
+ create_body = _docker.clear_empty_tables(create_body) or {}
+ extra_network = _docker.clear_empty_tables(extra_network) or {}
+
+ return create_body, extra_network
end
local upgrade = function(self, request)
- _docker:clear_status()
- -- get image name, image id, container name, configuration information
- local container_info = self.containers:inspect({id = request.id})
- if container_info.code > 300 and type(container_info.body) == "table" then
- return container_info
- end
- local image_name = container_info.body.Config.Image
- if not image_name:match(".-:.+") then image_name = image_name .. ":latest" end
- local old_image_id = container_info.body.Image
- local container_name = container_info.body.Name:sub(2)
-
- local image_id, res = update_image(self, image_name)
- if res and res.code ~= 200 then return res end
- if image_id == old_image_id then
- 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 < 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" }})
- if res and res.code < 300 then
- _docker:append_status("done\n")
- else
- return res
- end
-
- -- handle config
- local image_config = self.images:inspect({id = old_image_id}).body.Config
- local create_body, extra_network = get_config(container_info.body, image_config)
-
- -- create new container
- _docker:append_status("Container: Create" .. " " .. container_name .. "...")
- create_body = _docker.clear_empty_tables(create_body)
- res = self.containers:create({name = container_name, body = create_body})
- if res and res.code > 300 then return res end
- _docker:append_status("done\n")
-
- -- extra networks need to network connect action
- for k, v in pairs(extra_network) do
- _docker:append_status("Networks: Connect" .. " " .. container_name .. "...")
- res = self.networks:connect({id = k, body = {Container = container_name, EndpointConfig = v}})
- if res.code > 300 then return res end
-
- _docker:append_status("done\n")
- end
- _docker:clear_status()
- return res
+ _docker:clear_status()
+
+ local container_info = self.containers:inspect({id = request.id})
+
+ if container_info.code > 300 and type(container_info.body) == "table" then
+ return container_info
+ end
+
+ local image_name = container_info.body.Config.Image
+ if not image_name:match(".-:.+") then
+ image_name = image_name .. ":latest"
+ end
+
+ local old_image_id = container_info.body.Image
+ local container_name = container_info.body.Name:sub(2)
+
+ local image_id, res = update_image(self, image_name)
+ if res and res.code ~= 200 then
+ return res
+ end
+
+ if image_id == old_image_id then
+ 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 < 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" }})
+ if res and res.code < 300 then
+ _docker:append_status("done\n")
+ else
+ return res
+ end
+
+ local image_config = self.images:inspect({id = old_image_id}).body.Config
+ local create_body, extra_network = get_config(container_info.body, image_config)
+
+ -- create new container
+ _docker:append_status("Container: Create" .. " " .. container_name .. "...")
+ create_body = _docker.clear_empty_tables(create_body)
+ res = self.containers:create({name = container_name, body = create_body})
+ if res and res.code > 300 then
+ return res
+ end
+ _docker:append_status("done\n")
+
+ -- extra networks need to network connect action
+ for k, v in pairs(extra_network) do
+ _docker:append_status("Networks: Connect" .. " " .. container_name .. "...")
+ res = self.networks:connect({id = k, body = {Container = container_name, EndpointConfig = v}})
+ if res.code > 300 then
+ return res
+ end
+ _docker:append_status("done\n")
+ end
+
+ _docker:clear_status()
+ return res
end
local duplicate_config = function (self, request)
- local container_info = self.containers:inspect({id = request.id})
- if container_info.code > 300 and type(container_info.body) == "table" then return nil end
- local old_image_id = container_info.body.Image
- local image_config = self.images:inspect({id = old_image_id}).body.Config
- return get_config(container_info.body, image_config)
+ local container_info = self.containers:inspect({id = request.id})
+ if container_info.code > 300 and type(container_info.body) == "table" then
+ return nil
+ end
+
+ local old_image_id = container_info.body.Image
+ local image_config = self.images:inspect({id = old_image_id}).body.Config
+
+ return get_config(container_info.body, image_config)
end
_docker.new = function(option)
- local option = option or {}
- local remote = uci:get("dockerd", "globals", "remote_endpoint")
- options = {
- host = (remote == "true") and (option.host or uci:get("dockerd", "globals", "remote_host")) or nil,
- port = (remote == "true") and (option.port or uci:get("dockerd", "globals", "remote_port")) or nil,
- debug = option.debug or uci:get("dockerd", "globals", "debug") == 'true' and true or false,
- debug_path = option.debug_path or uci:get("dockerd", "globals", "debug_path") or "/tmp/.docker_debug"
- }
- options.socket_path = (remote ~= "true" or not options.host or not options.port) and (option.socket_path or uci:get("dockerd", "globals", "socket_path") or "/var/run/docker.sock") or nil
- local _new = docker.new(options)
- _new.options.status_path = uci:get("dockerd", "globals", "status_path") or "/tmp/.docker_status"
- _new.containers_upgrade = upgrade
- _new.containers_duplicate_config = duplicate_config
- return _new
+ local option = option or {}
+
+ local remote = uci:get("dockerd", "globals", "remote_endpoint")
+ options = {
+ host = (remote == "true") and (option.host or uci:get("dockerd", "globals", "remote_host")) or nil,
+ port = (remote == "true") and (option.port or uci:get("dockerd", "globals", "remote_port")) or nil,
+ debug = option.debug or uci:get("dockerd", "globals", "debug") == 'true' and true or false,
+ debug_path = option.debug_path or uci:get("dockerd", "globals", "debug_path") or "/tmp/.docker_debug"
+ }
+
+ options.socket_path = (remote ~= "true" or not options.host or not options.port) and (option.socket_path or uci:get("dockerd", "globals", "socket_path") or "/var/run/docker.sock") or nil
+
+ local _new = docker.new(options)
+ _new.options.status_path = uci:get("dockerd", "globals", "status_path") or "/tmp/.docker_status"
+ _new.containers_upgrade = upgrade
+ _new.containers_duplicate_config = duplicate_config
+
+ return _new
end
+
_docker.options={}
_docker.options.status_path = uci:get("dockerd", "globals", "status_path") or "/tmp/.docker_status"
_docker.append_status=function(self,val)
- if not val then return end
- local file_docker_action_status=io.open(self.options.status_path, "a+")
- file_docker_action_status:write(val)
- file_docker_action_status:close()
+ if not val then
+ return
+ end
+ local file_docker_action_status=io.open(self.options.status_path, "a+")
+ file_docker_action_status:write(val)
+ file_docker_action_status:close()
end
_docker.write_status=function(self,val)
- if not val then return end
- local file_docker_action_status=io.open(self.options.status_path, "w+")
- file_docker_action_status:write(val)
- file_docker_action_status:close()
+ if not val then
+ return
+ end
+ local file_docker_action_status=io.open(self.options.status_path, "w+")
+ file_docker_action_status:write(val)
+ file_docker_action_status:close()
end
_docker.read_status=function(self)
- return nixio.fs.readfile(self.options.status_path)
+ return nixio.fs.readfile(self.options.status_path)
end
_docker.clear_status=function(self)
- nixio.fs.remove(self.options.status_path)
+ nixio.fs.remove(self.options.status_path)
end
local status_cb = function(res, source, handler)
- res.body = res.body or {}
- while true do
- local chunk = source()
- if chunk then
- --standard output to res.body
- table.insert(res.body, chunk)
- handler(chunk)
- else
- return
- end
- end
+ res.body = res.body or {}
+ while true do
+ local chunk = source()
+ if chunk then
+ --standard output to res.body
+ table.insert(res.body, chunk)
+ handler(chunk)
+ else
+ return
+ end
+ end
end
--{"status":"Pulling from library\/debian","id":"latest"}
--{"status":"Digest: sha256:a63d0b2ecbd723da612abf0a8bdb594ee78f18f691d7dc652ac305a490c9b71a"}
--{"status":"Status: Downloaded newer image for debian:latest"}
_docker.pull_image_show_status_cb = function(res, source)
- return status_cb(res, source, function(chunk)
- local json_parse = luci.jsonc.parse
- local step = json_parse(chunk)
- if type(step) == "table" then
- local buf = _docker:read_status()
- local num = 0
- local str = '\t' .. (step.id and (step.id .. ": ") or "") .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n"
- if step.id then buf, num = buf:gsub("\t"..step.id .. ": .-\n", str) end
- if num == 0 then
- buf = buf .. str
- end
- _docker:write_status(buf)
- end
- end)
+ return status_cb(res, source, function(chunk)
+ local json_parse = luci.jsonc.parse
+ local step = json_parse(chunk)
+ if type(step) == "table" then
+ local buf = _docker:read_status()
+ local num = 0
+ local str = '\t' .. (step.id and (step.id .. ": ") or "") .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n"
+ if step.id then
+ buf, num = buf:gsub("\t"..step.id .. ": .-\n", str)
+ end
+ if num == 0 then
+ buf = buf .. str
+ end
+ _docker:write_status(buf)
+ end
+ end)
end
--{"status":"Downloading from https://downloads.openwrt.org/releases/19.07.0/targets/x86/64/openwrt-19.07.0-x86-64-generic-rootfs.tar.gz"}
--{"status":"Importing","progressDetail":{"current":1572391,"total":3821714},"progress":"[====================\u003e ] 1.572MB/3.822MB"}
--{"status":"sha256:d5304b58e2d8cc0a2fd640c05cec1bd4d1229a604ac0dd2909f13b2b47a29285"}
_docker.import_image_show_status_cb = function(res, source)
- return status_cb(res, source, function(chunk)
- local json_parse = luci.jsonc.parse
- local step = json_parse(chunk)
- if type(step) == "table" then
- local buf = _docker:read_status()
- local num = 0
- local str = '\t' .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n"
- if step.status then buf, num = buf:gsub("\t"..step.status .. " .-\n", str) end
- if num == 0 then
- buf = buf .. str
- end
- _docker:write_status(buf)
- end
- end
- )
+ return status_cb(res, source, function(chunk)
+ local json_parse = luci.jsonc.parse
+ local step = json_parse(chunk)
+ if type(step) == "table" then
+ local buf = _docker:read_status()
+ local num = 0
+ local str = '\t' .. (step.status and step.status or "") .. (step.progress and (" " .. step.progress) or "").."\n"
+ if step.status then
+ buf, num = buf:gsub("\t"..step.status .. " .-\n", str)
+ end
+ if num == 0 then
+ buf = buf .. str
+ end
+ _docker:write_status(buf)
+ end
+ end)
end
--- _docker.print_status_cb = function(res, source)
--- return status_cb(res, source, function(step)
--- luci.util.perror(step)
--- end
--- )
--- end
-
_docker.create_macvlan_interface = function(name, device, gateway, subnet)
- if not nixio.fs.access("/etc/config/network") or not nixio.fs.access("/etc/config/firewall") then return end
- if uci:get("dockerd", "globals", "remote_endpoint") == "true" then return end
- local ip = require "luci.ip"
- local if_name = "docker_"..name
- local dev_name = "macvlan_"..name
- local net_mask = tostring(ip.new(subnet):mask())
- local lan_interfaces
- -- add macvlan device
- uci:delete("network", dev_name)
- uci:set("network", dev_name, "device")
- uci:set("network", dev_name, "name", dev_name)
- uci:set("network", dev_name, "ifname", device)
- uci:set("network", dev_name, "type", "macvlan")
- uci:set("network", dev_name, "mode", "bridge")
- -- add macvlan interface
- uci:delete("network", if_name)
- uci:set("network", if_name, "interface")
- uci:set("network", if_name, "proto", "static")
- uci:set("network", if_name, "ifname", dev_name)
- uci:set("network", if_name, "ipaddr", gateway)
- uci:set("network", if_name, "netmask", net_mask)
- uci:foreach("firewall", "zone", function(s)
- if s.name == "lan" then
- local interfaces
- if type(s.network) == "table" then
- interfaces = table.concat(s.network, " ")
- uci:delete("firewall", s[".name"], "network")
- else
- interfaces = s.network and s.network or ""
- end
- interfaces = interfaces .. " " .. if_name
- interfaces = interfaces:gsub("%s+", " ")
- uci:set("firewall", s[".name"], "network", interfaces)
- end
- end)
- uci:commit("firewall")
- uci:commit("network")
- os.execute("ifup " .. if_name)
+ if not nixio.fs.access("/etc/config/network") or not nixio.fs.access("/etc/config/firewall") then
+ return
+ end
+
+ if uci:get("dockerd", "globals", "remote_endpoint") == "true" then
+ return
+ end
+
+ local ip = require "luci.ip"
+ local if_name = "docker_"..name
+ local dev_name = "macvlan_"..name
+ local net_mask = tostring(ip.new(subnet):mask())
+ local lan_interfaces
+
+ -- add macvlan device
+ uci:delete("network", dev_name)
+ uci:set("network", dev_name, "device")
+ uci:set("network", dev_name, "name", dev_name)
+ uci:set("network", dev_name, "ifname", device)
+ uci:set("network", dev_name, "type", "macvlan")
+ uci:set("network", dev_name, "mode", "bridge")
+
+ -- add macvlan interface
+ uci:delete("network", if_name)
+ uci:set("network", if_name, "interface")
+ uci:set("network", if_name, "proto", "static")
+ uci:set("network", if_name, "ifname", dev_name)
+ uci:set("network", if_name, "ipaddr", gateway)
+ uci:set("network", if_name, "netmask", net_mask)
+ uci:foreach("firewall", "zone", function(s)
+ if s.name == "lan" then
+ local interfaces
+ if type(s.network) == "table" then
+ interfaces = table.concat(s.network, " ")
+ uci:delete("firewall", s[".name"], "network")
+ else
+ interfaces = s.network and s.network or ""
+ end
+ interfaces = interfaces .. " " .. if_name
+ interfaces = interfaces:gsub("%s+", " ")
+ uci:set("firewall", s[".name"], "network", interfaces)
+ end
+ end)
+
+ uci:commit("firewall")
+ uci:commit("network")
+
+ os.execute("ifup " .. if_name)
end
_docker.remove_macvlan_interface = function(name)
- if not nixio.fs.access("/etc/config/network") or not nixio.fs.access("/etc/config/firewall") then return end
- if uci:get("dockerd", "globals", "remote_endpoint") == "true" then return end
- local if_name = "docker_"..name
- local dev_name = "macvlan_"..name
- uci:foreach("firewall", "zone", function(s)
- if s.name == "lan" then
- local interfaces
- if type(s.network) == "table" then
- interfaces = table.concat(s.network, " ")
- else
- interfaces = s.network and s.network or ""
- end
- interfaces = interfaces and interfaces:gsub(if_name, "")
- interfaces = interfaces and interfaces:gsub("%s+", " ")
- uci:set("firewall", s[".name"], "network", interfaces)
- end
- end)
- uci:commit("firewall")
- uci:delete("network", dev_name)
- uci:delete("network", if_name)
- uci:commit("network")
- os.execute("ip link del " .. if_name)
+ if not nixio.fs.access("/etc/config/network") or not nixio.fs.access("/etc/config/firewall") then
+ return
+ end
+
+ if uci:get("dockerd", "globals", "remote_endpoint") == "true" then
+ return
+ end
+
+ local if_name = "docker_"..name
+ local dev_name = "macvlan_"..name
+ uci:foreach("firewall", "zone", function(s)
+ if s.name == "lan" then
+ local interfaces
+ if type(s.network) == "table" then
+ interfaces = table.concat(s.network, " ")
+ else
+ interfaces = s.network and s.network or ""
+ end
+ interfaces = interfaces and interfaces:gsub(if_name, "")
+ interfaces = interfaces and interfaces:gsub("%s+", " ")
+ uci:set("firewall", s[".name"], "network", interfaces)
+ end
+ end)
+
+ uci:delete("network", dev_name)
+ uci:delete("network", if_name)
+ uci:commit("network")
+ uci:commit("firewall")
+
+ os.execute("ip link del " .. if_name)
end
return _docker