luci-app-dockerman: bump to v0.5.9

This commit is contained in:
CN_SZTL 2020-04-10 01:07:02 +08:00
parent 2c1bb599de
commit 364079b1fa
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
14 changed files with 119 additions and 36 deletions

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-dockerman
PKG_VERSION:=v0.5.7
PKG_VERSION:=v0.5.9
PKG_RELEASE:=beta
PKG_MAINTAINER:=lisaac <https://github.com/lisaac/luci-app-dockerman>
PKG_LICENSE:=AGPL-3.0

View File

@ -20,7 +20,7 @@ local get_ports = function(d)
local data
if d.HostConfig and d.HostConfig.PortBindings then
for inter, out in pairs(d.HostConfig.PortBindings) do
data = (data and (data .. "<br>") or "") .. out[1]["HostPort"] .. ":" .. inter
data = (data and (data .. "<br>") or "") .. out[1]["HostPort"] .. ":" .. inter
end
end
return data
@ -186,6 +186,11 @@ btnstop.template = "dockerman/cbi/inlinebutton"
btnstop.inputtitle=translate("Stop")
btnstop.inputstyle = "reset"
btnstop.forcewrite = true
btnkill=action_section:option(Button, "_kill")
btnkill.template = "dockerman/cbi/inlinebutton"
btnkill.inputtitle=translate("Kill")
btnkill.inputstyle = "reset"
btnkill.forcewrite = true
btnupgrade=action_section:option(Button, "_upgrade")
btnupgrade.template = "dockerman/cbi/inlinebutton"
btnupgrade.inputtitle=translate("Upgrade")
@ -217,6 +222,9 @@ end
btnstop.write = function(self, section)
start_stop_remove(m,"stop")
end
btnkill.write = function(self, section)
start_stop_remove(m,"kill")
end
btnduplicate.write = function(self, section)
luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer/duplicate/"..container_id))
end
@ -466,6 +474,13 @@ elseif action == "file" then
m.reset = false
filesection.template = "dockerman/container_file"
filesection.container = container_id
elseif action == "inspect" then
local inspectsection= m:section(SimpleSection)
inspectsection.syslog = luci.jsonc.stringify(container_info, true)
inspectsection.title = translate("Container Inspect")
inspectsection.template = "dockerman/logs"
m.submit = false
m.reset = false
elseif action == "logs" then
local logsection= m:section(SimpleSection)
local logs = ""

View File

@ -163,6 +163,11 @@ btnstop.template = "dockerman/cbi/inlinebutton"
btnstop.inputtitle=translate("Stop")
btnstop.inputstyle = "reset"
btnstop.forcewrite = true
btnkill=action_section:option(Button, "_kill")
btnkill.template = "dockerman/cbi/inlinebutton"
btnkill.inputtitle=translate("Kill")
btnkill.inputstyle = "reset"
btnkill.forcewrite = true
btnremove=action_section:option(Button, "_remove")
btnremove.template = "dockerman/cbi/inlinebutton"
btnremove.inputtitle=translate("Remove")
@ -183,5 +188,8 @@ end
btnstop.write = function(self, section)
start_stop_remove(m,"stop")
end
btnkill.write = function(self, section)
start_stop_remove(m,"kill")
end
return m

View File

@ -32,8 +32,8 @@ end
local resolve_cli = function(cmd_line)
local config = {advance = 1}
local key_no_val = '|t|d|i|tty|rm|read_only|interactive|init|help|detach|privileged|'
local key_with_val = '|sysctl|add_host|a|attach|blkio_weight_device|cap_add|cap_drop|device|device_cgroup_rule|device_read_bps|device_read_iops|device_write_bps|device_write_iops|dns|dns_option|dns_search|e|env|env_file|expose|group_add|l|label|label_file|link|link_local_ip|log_driver|log_opt|network_alias|p|publish|security_opt|storage_opt|tmpfs|v|volume|volumes_from|blkio_weight|cgroup_parent|cidfile|cpu_period|cpu_quota|cpu_rt_period|cpu_rt_runtime|c|cpu_shares|cpus|cpuset_cpus|cpuset_mems|detach_keys|disable_content_trust|domainname|entrypoint|gpus|health_cmd|health_interval|health_retries|health_start_period|health_timeout|h|hostname|ip|ip6|ipc|isolation|kernel_memory|log_driver|mac_address|m|memory|memory_reservation|memory_swap|memory_swappiness|mount|name|network|no_healthcheck|oom_kill_disable|oom_score_adj|pid|pids_limit|P|publish_all|restart|runtime|shm_size|sig_proxy|stop_signal|stop_timeout|ulimit|u|user|userns|uts|volume_driver|w|workdir|'
local key_no_val = '|t|d|i|tty|rm|read_only|interactive|init|help|detach|privileged|P|publish_all|'
local key_with_val = '|sysctl|add_host|a|attach|blkio_weight_device|cap_add|cap_drop|device|device_cgroup_rule|device_read_bps|device_read_iops|device_write_bps|device_write_iops|dns|dns_option|dns_search|e|env|env_file|expose|group_add|l|label|label_file|link|link_local_ip|log_driver|log_opt|network_alias|p|publish|security_opt|storage_opt|tmpfs|v|volume|volumes_from|blkio_weight|cgroup_parent|cidfile|cpu_period|cpu_quota|cpu_rt_period|cpu_rt_runtime|c|cpu_shares|cpus|cpuset_cpus|cpuset_mems|detach_keys|disable_content_trust|domainname|entrypoint|gpus|health_cmd|health_interval|health_retries|health_start_period|health_timeout|h|hostname|ip|ip6|ipc|isolation|kernel_memory|log_driver|mac_address|m|memory|memory_reservation|memory_swap|memory_swappiness|mount|name|network|no_healthcheck|oom_kill_disable|oom_score_adj|pid|pids_limit|restart|runtime|shm_size|sig_proxy|stop_signal|stop_timeout|ulimit|u|user|userns|uts|volume_driver|w|workdir|'
local key_abb = {net='network',a='attach',c='cpu-shares',d='detach',e='env',h='hostname',i='interactive',l='label',m='memory',p='publish',P='publish_all',t='tty',u='user',v='volume',w='workdir'}
local key_with_list = '|sysctl|add_host|a|attach|blkio_weight_device|cap_add|cap_drop|device|device_cgroup_rule|device_read_bps|device_read_iops|device_write_bps|device_write_iops|dns|dns_option|dns_search|e|env|env_file|expose|group_add|l|label|label_file|link|link_local_ip|log_driver|log_opt|network_alias|p|publish|security_opt|storage_opt|tmpfs|v|volume|volumes_from|'
local key = nil
@ -68,6 +68,10 @@ local resolve_cli = function(cmd_line)
config[key_abb["d"]] = true
key:gsub("d", "")
end
if key:match("P") then
config[key_abb["P"]] = true
key:gsub("P", "")
end
if key == "" then key = nil end
end
end
@ -180,6 +184,7 @@ elseif cmd_line and cmd_line:match("^duplicate/[^/]+$") then
default_config.dns = create_body.HostConfig.Dns
default_config.volume = create_body.HostConfig.Binds
default_config.cap_add = create_body.HostConfig.CapAdd
default_config.publish_all = create_body.HostConfig.PublishAllPorts
if create_body.HostConfig.Sysctls and type(create_body.HostConfig.Sysctls) == "table" then
default_config.sysctl = {}
@ -188,6 +193,13 @@ elseif cmd_line and cmd_line:match("^duplicate/[^/]+$") then
end
end
if create_body.HostConfig.LogConfig and create_body.HostConfig.LogConfig.Config and type(create_body.HostConfig.LogConfig.Config) == "table" then
default_config.log_opt = {}
for k, v in pairs(create_body.HostConfig.LogConfig.Config) do
table.insert( default_config.log_opt, k.."="..v )
end
end
if create_body.HostConfig.PortBindings and type(create_body.HostConfig.PortBindings) == "table" then
default_config.publish = {}
for k, v in pairs(create_body.HostConfig.PortBindings) do
@ -340,6 +352,13 @@ d.rmempty = true
d.default = default_config.hostname or nil
d:depends("advance", 1)
d = s:option(Flag, "publish_all", translate("Exposed All Ports(-P)"), translate("Allocates an ephemeral host port for all of a container's exposed ports"))
d.rmempty = true
d.disabled = 0
d.enabled = 1
d.default = default_config.publish_all and 1 or 0
d:depends("advance", 1)
d = s:option(DynamicList, "device", translate("Device(--device)"), translate("Add host device to the container"))
d.placeholder = "/dev/sda:/dev/xvdc:rwm"
d.rmempty = true
@ -364,33 +383,39 @@ d.rmempty = true
d:depends("advance", 1)
d.default = default_config.cap_add or nil
d = s:option(Value, "cpus", translate("CPUs"), translate("Number of CPUs. Number is a fractional number. 0.000 means no limit."))
d = s:option(Value, "cpus", translate("CPUs"), translate("Number of CPUs. Number is a fractional number. 0.000 means no limit"))
d.placeholder = "1.5"
d.rmempty = true
d:depends("advance", 1)
d.datatype="ufloat"
d.default = default_config.cpus or nil
d = s:option(Value, "cpu_shares", translate("CPU Shares Weight"), translate("CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024."))
d = s:option(Value, "cpu_shares", translate("CPU Shares Weight"), translate("CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024"))
d.placeholder = "1024"
d.rmempty = true
d:depends("advance", 1)
d.datatype="uinteger"
d.default = default_config.cpu_shares or nil
d = s:option(Value, "memory", translate("Memory"), translate("Memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M."))
d = s:option(Value, "memory", translate("Memory"), translate("Memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M"))
d.placeholder = "128m"
d.rmempty = true
d:depends("advance", 1)
d.default = default_config.memory or nil
d = s:option(Value, "blkio_weight", translate("Block IO Weight"), translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000."))
d = s:option(Value, "blkio_weight", translate("Block IO Weight"), translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000"))
d.placeholder = "500"
d.rmempty = true
d:depends("advance", 1)
d.datatype="uinteger"
d.default = default_config.blkio_weight or nil
d = s:option(DynamicList, "log_opt", translate("Log driver options"), translate("The logging configuration for this container"))
d.placeholder = "max-size=1m"
d.rmempty = true
d:depends("advance", 1)
d.default = default_config.log_opt or nil
for _, v in ipairs (networks) do
if v.Name then
local parent = v.Options and v.Options.parent or nil
@ -415,6 +440,7 @@ m.handle = function(self, state, data)
local name = data.name or ("luci_" .. os.date("%Y%m%d%H%M%S"))
local hostname = data.hostname
local tty = type(data.tty) == "number" and (data.tty == 1 and true or false) or default_config.tty or false
local publish_all = type(data.publish_all) == "number" and (data.publish_all == 1 and true or false) or default_config.publish_all or false
local interactive = type(data.interactive) == "number" and (data.interactive == 1 and true or false) or default_config.interactive or false
local image = data.image
local user = data.user
@ -436,6 +462,16 @@ m.handle = function(self, state, data)
end
end
end
local log_opt = {}
tmp = data.log_opt
if type(tmp) == "table" then
for i, v in ipairs(tmp) do
local k,v1 = v:match("(.-)=(.+)")
if k and v1 then
log_opt[k]=v1
end
end
end
local network = data.network
local ip = (network ~= "bridge" and network ~= "host" and network ~= "none") and data.ip or nil
local volume = data.volume
@ -536,6 +572,7 @@ m.handle = function(self, state, data)
create_body.HostConfig.CpuShares = tonumber(cpu_shares)
create_body.HostConfig.NanoCPUs = tonumber(cpus) * 10 ^ 9
create_body.HostConfig.BlkioWeight = tonumber(blkio_weight)
create_body.HostConfig.PublishAllPorts = publish_all
if create_body.HostConfig.NetworkMode ~= network then
-- network mode changed, need to clear duplicate config
create_body.NetworkingConfig = nil
@ -564,6 +601,7 @@ m.handle = function(self, state, data)
create_body["HostConfig"]["Devices"] = device
create_body["HostConfig"]["Sysctls"] = sysctl
create_body["HostConfig"]["CapAdd"] = cap_add
create_body["HostConfig"]["LogConfig"] = next(log_opt) ~= nil and { Config = log_opt } or nil
if network == "bridge" then
create_body["HostConfig"]["Links"] = link
@ -608,4 +646,4 @@ m.handle = function(self, state, data)
end
end
return m
return m

View File

@ -56,7 +56,7 @@ d.default="l3"
d:value("l2", "l2")
d:value("l3", "l3")
d = s:option(Flag, "ingress", translate("Ingress"), translate("Ingress network is the network which provides the routing-mesh in swarm mode."))
d = s:option(Flag, "ingress", translate("Ingress"), translate("Ingress network is the network which provides the routing-mesh in swarm mode"))
d.rmempty = true
d.disabled = 0
d.enabled = 1

View File

@ -129,8 +129,8 @@ local get_config = function(container_config, image_config)
-- 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
-- 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

View File

@ -5,6 +5,7 @@
<li id="cbi-tab-container_stats"><a id="a-cbi-tab-container_stats" href=""><%:Stats%></a></li>
<li id="cbi-tab-container_file"><a id="a-cbi-tab-container_file" href=""><%:File%></a></li>
<li id="cbi-tab-container_console"><a id="a-cbi-tab-container_console" href=""><%:Console%></a></li>
<li id="cbi-tab-container_inspect"><a id="a-cbi-tab-container_inspect" href=""><%:Inspect%></a></li>
<li id="cbi-tab-container_logs"><a id="a-cbi-tab-container_logs" href=""><%:Logs%></a></li>
</ul>
@ -14,7 +15,7 @@
let path = p.split(re)
let container_id = path[1].split('/')[0] || path[1]
let action = path[1].split('/')[1] || "info"
let actions=["info","resources","stats","file","console","logs"]
let actions=["info","resources","stats","file","console","logs","inspect"]
actions.forEach(function(item) {
document.getElementById("a-cbi-tab-container_" + item).href= path[0]+"/admin/docker/container/"+container_id+'/'+item
if (action === item) {

View File

@ -33,7 +33,7 @@
formData.append('upload-path', uploadPath)
formData.append('upload-archive', uploadArchive.files[0])
let xhr = new XMLHttpRequest()
xhr.open("POST", "/cgi-bin/luci/admin/docker/container_put_archive/<%=self.container%>", true)
xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/container_put_archive")%>/<%=self.container%>', true)
xhr.onload = function() {
if (xhr.status == 200) {
uploadArchive.value = ''
@ -58,6 +58,6 @@
})
return
}
window.open("/cgi-bin/luci/admin/docker/container_get_archive/?id=<%=self.container%>&path=" + encodeURIComponent(downloadPath))
window.open('<%=luci.dispatcher.build_url("admin/docker/container_get_archive")%>?id=<%=self.container%>&path=' + encodeURIComponent(downloadPath))
}
</script>

View File

@ -25,7 +25,7 @@
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
XHR.poll(interval, '/cgi-bin/luci/admin/docker/container_stats/<%=self.container_id%>', { status: 1 },
XHR.poll(interval, '<%=luci.dispatcher.build_url("admin/docker/container_stats")%>/<%=self.container_id%>', { status: 1 },
function (x, info) {
var e;

View File

@ -19,7 +19,7 @@
formData.append('tag', valITag.value)
let xhr = new XMLHttpRequest()
uci_confirm_docker()
xhr.open("POST", "<%=url('admin/docker/images_import')%>", true)
xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
xhr.onload = function () {
location.reload()
}
@ -40,7 +40,7 @@
formData.append('upload-archive', fileimport.files[0])
let xhr = new XMLHttpRequest()
uci_confirm_docker()
xhr.open("POST", "<%=url('admin/docker/images_import')%>", true)
xhr.open("POST", "<%=luci.dispatcher.build_url('admin/docker/images_import')%>", true)
xhr.onload = function () {
fileimport.value = ''
location.reload()
@ -51,7 +51,7 @@
let new_tag = function (image_id) {
let new_tag = prompt("<%:New tag%>\n<%:Image%>" + "ID: " + image_id + "\n<%:Please input new tag%>:", "")
if (new_tag) {
(new XHR()).post("<%=url('admin/docker/images_tag')%>",
(new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_tag')%>",
{ id: image_id, tag: new_tag },
function (r) {
if (r.status == 201) {
@ -70,7 +70,7 @@
let un_tag = function (tag) {
if (tag.match("<none>")) return
if (confirm("<%:Remove tag%>: " + tag + " ?")) {
(new XHR()).post("<%=url('admin/docker/images_untag')%>",
(new XHR()).post("<%=luci.dispatcher.build_url('admin/docker/images_untag')%>",
{ tag: tag },
function (r) {
if (r.status == 200) {

View File

@ -20,7 +20,7 @@
formData.append('upload-archive', fileLoad.files[0])
let xhr = new XMLHttpRequest()
uci_confirm_docker()
xhr.open("POST", "/cgi-bin/luci/admin/docker/images_load", true)
xhr.open("POST", '<%=luci.dispatcher.build_url("admin/docker/images_load")%>', true)
xhr.onload = function() {
location.reload()
}

View File

@ -73,7 +73,7 @@
let reg_rem =/`#.+`/g// the command has `# `
cmd_line = cmd_line.replace(/^docker\s+(run|create)/,"DOCKERCLI").replace(reg_rem, " ").replace(reg_muti_line, " ").replace(reg_space, " ")
console.log(cmd_line)
window.location.href = "/cgi-bin/luci/admin/docker/newcontainer/" + encodeURI(cmd_line)
window.location.href = '<%=luci.dispatcher.build_url("admin/docker/newcontainer")%>/' + encodeURI(cmd_line)
}
function clear_text(){

View File

@ -136,7 +136,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
<div class="pure-u-3-5">
<h4 style="text-align: right; font-size: 1rem"><%:Containers%></h4>
<h4 style="text-align: right;">
<%- if self.containers_total ~= "-" then -%><a href="/cgi-bin/luci/admin/docker/containers"><%- end -%>
<%- if self.containers_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/containers")%>'><%- end -%>
<span style="font-size: 2rem; color: #2dce89;"><%=self.containers_running%></span>
<span style="font-size: 1rem; color: #8898aa !important;">/<%=self.containers_total%></span>
<%- if self.containers_total ~= "-" then -%></a><%- end -%>
@ -160,7 +160,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
<div class="pure-u-3-5">
<h4 style="text-align: right; font-size: 1rem"><%:Images%></h4>
<h4 style="text-align: right;">
<%- if self.images_total ~= "-" then -%><a href="/cgi-bin/luci/admin/docker/images"><%- end -%>
<%- if self.images_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/images")%>'><%- end -%>
<span style="font-size: 2rem; color: #2dce89;"><%=self.images_used%></span>
<span style="font-size: 1rem; color: #8898aa !important;">/<%=self.images_total%></span>
<%- if self.images_total ~= "-" then -%></a><%- end -%>
@ -192,7 +192,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
<div class="pure-u-3-5">
<h4 style="text-align: right; font-size: 1rem"><%:Networks%></h4>
<h4 style="text-align: right;">
<%- if self.networks_total ~= "-" then -%><a href="/cgi-bin/luci/admin/docker/networks"><%- end -%>
<%- if self.networks_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/networks")%>'><%- end -%>
<span style="font-size: 2rem; color: #2dce89;"><%=self.networks_total%></span>
<!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
<%- if self.networks_total ~= "-" then -%></a><%- end -%>
@ -269,7 +269,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
<div class="pure-u-3-5">
<h4 style="text-align: right; font-size: 1rem"><%:Volumes%></h4>
<h4 style="text-align: right;">
<%- if self.volumes_total ~= "-" then -%><a href="/cgi-bin/luci/admin/docker/volumes"><%- end -%>
<%- if self.volumes_total ~= "-" then -%><a href='<%=luci.dispatcher.build_url("admin/docker/volumes")%>'><%- end -%>
<span style="font-size: 2rem; color: #2dce89;"><%=self.volumes_total%></span>
<!-- <span style="font-size: 1rem; color: #8898aa !important;">/20</span> -->
<%- if self.volumes_total ~= "-" then -%></a><%- end -%>

View File

@ -97,26 +97,26 @@ msgstr "信息"
msgid "CPUs"
msgstr "CPU数量"
msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit."
msgstr "CPU数量数字是小数0.000表示没有限制"
msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit"
msgstr "CPU数量数字是小数0.000表示没有限制"
msgid "CPU Shares Weight"
msgstr "CPU份额权重"
msgid "CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024."
msgid "CPU shares relative weight, if 0 is set, the system will ignore the value and use the default of 1024"
msgstr "CPU份额相对权重如果设置为0则系统将忽略该值并使用默认值1024。"
msgid "Memory"
msgstr "内存"
msgid "Memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M."
msgstr "内存限制 (格式: <容量>[<单位>]). 数字是一个正整数。单位可以是bkm或g之一。最小为4M"
msgid "Memory limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M"
msgstr "内存限制 (格式: <容量>[<单位>]). 数字是一个正整数。单位可以是bkm或g之一。最小为4M"
msgid "Block IO Weight"
msgstr "IO 权重"
msgid "Block IO weight (relative weight) accepts a weight value between 10 and 1000."
msgstr "IO 权重 (相对权重) 接受10到1000之间的权重值"
msgid "Block IO weight (relative weight) accepts a weight value between 10 and 1000"
msgstr "IO 权重 (相对权重) 接受10到1000之间的权重值"
msgid "Container Logs"
msgstr "容器日志"
@ -202,8 +202,8 @@ msgstr "Macvlan模式"
msgid "Ipvlan Mode"
msgstr "Ipvlan模式"
msgid "Ingress network is the network which provides the routing-mesh in swarm mode."
msgstr "Ingress网络是在群集模式下提供路由网的网络"
msgid "Ingress network is the network which provides the routing-mesh in swarm mode"
msgstr "Ingress网络是在群集模式下提供路由网的网络"
msgid "Options"
msgstr "选项"
@ -446,4 +446,25 @@ msgid "Create macvlan interface"
msgstr "创建 macvlan 接口"
msgid "Auto create macvlan interface in Openwrt"
msgstr "在 Openwrt 中自动创建 macvlan 接口"
msgstr "在 Openwrt 中自动创建 macvlan 接口"
msgid "Kill"
msgstr "强制关闭"
msgid "Exposed All Ports(-P)"
msgstr "暴露所有端口"
msgid "Allocates an ephemeral host port for all of a container's exposed ports"
msgstr "为容器的所有暴露端口分配临时主机端口"
msgid "Log driver options"
msgstr "日志选项"
msgid "The logging configuration for this container"
msgstr "容器日志配置"
msgid "A list of kernel capabilities to add to the container"
msgstr "添加到容器的内核功能列表"
msgid "Sysctls (kernel parameters) options"
msgstr "Sysctls内核参数选项"