diff --git a/README.md b/README.md index e92835abd..10b733c62 100755 --- a/README.md +++ b/README.md @@ -1,186 +1 @@ # OpenWrt OpenMPTCProuter feed - - -This is the OpenWrt OpenMPTCProuter feed containing all modified and necessary packages to build the OpenMPTCProuter image. - -For More information, see [https://github.com/ysurac/openmptcprouter](https://github.com/ysurac/openmptcprouter) and [https://www.openmptcprouter.com](https://www.openmptcprouter.com/). - - -## Glorytun -*Source:* [https://github.com/angt/glorytun](https://github.com/angt/glorytun) - -*Description:* A small, simple and secure VPN - - -A LuCI interface was made to make it easier to use. It's used in OpenMPTCProuter to redirect ports from the VPS to the router and for UDP/ICMP traffic from the router. - - -## Shadowsocks-libev -*Source:* [https://github.com/shadowsocks/shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev) - -*Description:* A secure socks5 proxy - - -MPTCP support is added in LuCI interface and init scripts. IPv6 support added. - -## Shadowsocks-v2ray-plugin-bin -*Source:* [https://github.com/shadowsocks/v2ray-plugin](https://github.com/shadowsocks/v2ray-plugin) - -*Description:* V2ray plugin for Shadowsocks - -Support is added in ShadowSocks LuCI interface and init scripts. - - -## Simple-obfs -*Source:* [https://github.com/shadowsocks/simple-obfs](https://github.com/shadowsocks/simple-obfs) - -*Description:* A simple obfuscating tool, designed as plugin server of shadowsocks. - - -Support is added in ShadowSocks LuCI interface and init scripts. - - -## SpeedTestC -*Source:* [https://github.com/mobrembski/SpeedTestC](https://github.com/mobrembski/SpeedTestC) - -*Description:* Client for SpeedTest.net infrastructure written in pure C99 standard using only POSIX libraries. - -Used to test speed. No LuCI interface. - - -## Nginx -*Source:* [https://www.nginx.org](https://www.nginx.org) - -*Description:* nginx is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server. - - -A LuCI interface for TCP/UDP stream is added. Used for TCP/UDP failover. - - -## luci-proto-ipv6 -*Source:* [https://github.com/openwrt/luci](https://github.com/openwrt/luci) - -*Description:* Luci support for DHCPv6/6in4/6to4/6rd/DS-Lite/aiccu - -Added support to gateway set by user for 6in4. Used for IPv6 over the glorytun IPv4 VPN. - - -## luci-omr-bypass -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-omr-bypass](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-omr-bypass) - -*Description:* Luci interface to bypass domains, IPs and networks with shadowsocks - -Domains, IPs, networks and protocol (using DPI) added are bypassed when shadowsocks is used. This can be used when VPS IP is blacklisted from some sites. - - -## omr-tracker -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-tracker](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-tracker) - -*Description:* Track connection status. This check if gateway is up then check if the connection work. If it's not working this execute scripts. This also detect if ShadowSocks is up or not. - -This is used for OpenMPTCProuter failover. - - -## luci-omr-tracker -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-omr-tracker](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-omr-tracker) - -*Description:* Luci interface to omr-tracker - -Interface to omr-tracker. - - -## luci-app-iperf -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-iperf](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-iperf) - -*Description:* Luci interface to iPerf - - -## omr-6in4 -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-6in4](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-6in4) - -*Description:* Set tunnel configuration by tracking tunnel configuration. - - -## omr-update -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-update](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/omr-update) - -*Description:* Update old config with new settings. - - -## luci-app-mptcp -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-mptcp](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-mptcp) - -*Description:* Luci interface for all MPTCP settings - - -## luci-app-openmptcprouter -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-openmptcprouter](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/luci-app-openmptcprouter) - -*Description:* Wizard for OpenMPTCProuter settings and status page - - -## mptcp -*Source:* [https://github.com/Ysurac/openmptcprouter-feeds/tree/master/mptcp](https://github.com/Ysurac/openmptcprouter-feeds/tree/master/mptcp) - -*Description:* This package set all MPTCP settings - - -## ndisc6 -*Source:* [http://www.remlab.net/files/ndisc6](http://www.remlab.net/files/ndisc6) - -*Description:* An ICMPv6 neighbour discovery tool - -This is used to check if there is no other IPv6 route announced on the network - - -## mlvpn -*Source:* [https://github.com/markfoodyburton/MLVPN/tree/new-reorder](https://github.com/markfoodyburton/MLVPN/tree/new-reorder) - -*Description:* Multi-link VPN - -This is an other way to aggregate same latency connections - - -## dsvpn -*Source:* [https://github.com/jedisct1/dsvpn][https://github.com/jedisct1/dsvpn] - -*Description:* A Dead Simple VPN - -A simple TCP VPN - - -## ndpi-netfilter2 -*Source:* [https://github.com/vel21ripn/nDPI](https://github.com/vel21ripn/nDPI) - -*Description:* Open Source Deep Packet Inspection Software Toolkit - -This is used to bypass a protocol - - -## tracebox -*Source:* [https://github.com/tracebox/tracebox](https://github.com/tracebox/tracebox) - -*Description:* A middlebox detection tool - - -## Shortcut-FE -*Source:* [https://github.com/coolsnowwolf/lede/tree/master/package/lean/shortcut-fe](https://github.com/coolsnowwolf/lede/tree/master/package/lean/shortcut-fe) - -*Description:* Shortcut is an in-Linux-kernel IP packet forwarding engine. - - -## V2Ray -*Source:* [https://github.com/v2fly/v2ray-core](https://github.com/v2fly/v2ray-core) - -*Description:* A platform for building proxies to bypass network restrictions. - -This is used as proxy, alternative to Shadowsocks - - - -# License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FYsurac%2Fopenmptcprouter-feeds.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FYsurac%2Fopenmptcprouter-feeds?ref=badge_large) - -## Translation status - -[![Translation status](https://weblate.openmptcprouter.com/widgets/omr/-/multi-auto.svg)](https://weblate.openmptcprouter.com/engage/omr/?utm_source=widget) diff --git a/glorytun/Makefile b/glorytun/Makefile index 95d7ed3aa..837f1903f 100755 --- a/glorytun/Makefile +++ b/glorytun/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=glorytun PKG_RELEASE:=6 PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=6d58536f4232fea8eaa10fb60aace8ba11f29ed6 +PKG_SOURCE_VERSION:=0c3b03cf0215e0896fd8e7e91be92efa77f6a2d1 PKG_SOURCE:=glorytun-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/Ysurac/glorytun.git PKG_VERSION:=0.0.35-$(PKG_SOURCE_VERSION) diff --git a/glorytun/init b/glorytun/init index c0011edc1..a21afcd9f 100755 --- a/glorytun/init +++ b/glorytun/init @@ -82,7 +82,7 @@ start_instance() { retry count -1 const 5000000 \ timeout ${timeout} \ keepalive count 5 idle 20 interval 2 \ - buffer-size 32768 + buffer-size 327680 procd_set_param respawn 0 30 0 procd_set_param file /tmp/${PROG_NAME}-${1}.key diff --git a/libmbim/Makefile b/libmbim/Makefile deleted file mode 100755 index cfcb5ba96..000000000 --- a/libmbim/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright (C) 2016 Velocloud Inc. -# Copyright (C) 2016 Aleksander Morgado -# -# This is free software, licensed under the GNU General Public License v2. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=libmbim -PKG_SOURCE_VERSION:=1.29.2 -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git -#PKG_MIRROR_HASH:=0b0b46016738fc22355d5a58c8a2d1b2f04906c49c51a50b57a09640d13b00b7 - -PKG_MAINTAINER:=Nicholas Smith - -include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/nls.mk -include $(INCLUDE_DIR)/meson.mk - -TARGET_CFLAGS += -ffunction-sections -fdata-sections -fno-merge-all-constants -fmerge-constants -TARGET_LDFLAGS += -Wl,--gc-sections - -MESON_ARGS += \ - -Dintrospection=false \ - -Dman=false \ - -Dbash_completion=false \ - -Db_lto=true - -define Package/libmbim - SECTION:=libs - CATEGORY:=Libraries - DEPENDS:=+glib2 - TITLE:=Helper library and utils to talk to MBIM enabled modems - URL:=https://www.freedesktop.org/wiki/Software/libmbim - LICENSE:=LGPL-2.0-or-later - LICENSE_FILES:=COPYING.LIB -endef - -define Package/libmbim/description - Helper library to talk to MBIM enabled modems. - Add mbim-utils for extra utilities. -endef - -define Package/mbim-utils - SECTION:=utils - CATEGORY:=Utilities - DEPENDS:=+libmbim - TITLE:=Utilities to talk to MBIM enabled modems - URL:=https://www.freedesktop.org/wiki/Software/libmbim - LICENSE:=GPL-2.0-or-later - LICENSE_FILES:=COPYING -endef - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include - $(CP) \ - $(PKG_INSTALL_DIR)/usr/include/libmbim-glib \ - $(1)/usr/include/ - - $(INSTALL_DIR) $(1)/usr/lib - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libmbim*.so* \ - $(1)/usr/lib/ - - $(INSTALL_DIR) $(1)/usr/lib/pkgconfig - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/mbim-glib.pc \ - $(1)/usr/lib/pkgconfig -endef - -define Package/libmbim/install - $(INSTALL_DIR) \ - $(1)/usr/lib \ - $(1)/usr/libexec - - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libmbim*.so.* \ - $(1)/usr/lib/ - - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/libexec/mbim-proxy $(1)/usr/libexec/ -endef - -define Package/mbim-utils/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mbimcli $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mbim-network $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,libmbim)) -$(eval $(call BuildPackage,mbim-utils)) diff --git a/libqmi/Config.in b/libqmi/Config.in deleted file mode 100755 index 7dfa7ca52..000000000 --- a/libqmi/Config.in +++ /dev/null @@ -1,31 +0,0 @@ -menu "Configuration" - depends on PACKAGE_libqmi - -config LIBQMI_WITH_MBIM_QMUX - bool "Include MBIM QMUX service support" - default y - help - Compile libqmi with QMI-over-MBIM support - -config LIBQMI_WITH_QRTR_GLIB - bool "Include QRTR support" - default y - help - Compile libqmi with QRTR support - -choice - prompt "Select QMI message collection to build" - default LIBQMI_COLLECTION_BASIC - - config LIBQMI_COLLECTION_MINIMAL - depends on !MODEMMANAGER_WITH_QMI - bool "minimal" - - config LIBQMI_COLLECTION_BASIC - bool "basic (default)" - - config LIBQMI_COLLECTION_FULL - bool "full" -endchoice - -endmenu diff --git a/libqmi/Makefile b/libqmi/Makefile deleted file mode 100755 index cecee6cb6..000000000 --- a/libqmi/Makefile +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (C) 2016 Velocloud Inc. -# Copyright (C) 2016 Aleksander Morgado -# -# This is free software, licensed under the GNU General Public License v2. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=libqmi -PKG_SOURCE_VERSION:=1.33.3 -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git -#PKG_MIRROR_HASH:=711d16d75a6a9afaefcf2be1bc845a4a6181dff786dfbd079e41e91279a0be91 - -PKG_MAINTAINER:=Nicholas Smith - -include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/nls.mk -include $(INCLUDE_DIR)/meson.mk - -TARGET_CFLAGS += -ffunction-sections -fdata-sections -fno-merge-all-constants -fmerge-constants -TARGET_LDFLAGS += -Wl,--gc-sections - -define Package/libqmi/config - source "$(SOURCE)/Config.in" -endef - -define Package/libqmi - SECTION:=libs - CATEGORY:=Libraries - DEPENDS:= \ - +glib2 \ - +LIBQMI_WITH_MBIM_QMUX:libmbim \ - +LIBQMI_WITH_QRTR_GLIB:libqrtr-glib - TITLE:=Helper library to talk to QMI enabled modems - URL:=https://www.freedesktop.org/wiki/Software/libqmi - LICENSE:=LGPL-2.0-or-later - LICENSE_FILES:=COPYING.LIB -endef - -define Package/libqmi/description - Helper library talk to QMI enabled modems. - Add qmi-utils for extra utilities. -endef - -define Package/qmi-utils - SECTION:=utils - CATEGORY:=Utilities - DEPENDS:=+libqmi - TITLE:=Utilities to talk to QMI enabled modems - URL:=https://www.freedesktop.org/wiki/Software/libqmi - LICENSE:=GPL-2.0-or-later - LICENSE_FILES:=COPYING -endef - -define Package/libqmi-utils/description - Utils to talk to QMI enabled modems -endef - -MESON_ARGS += \ - -Dudev=false \ - -Dintrospection=false \ - -Dman=false \ - -Dbash_completion=false \ - -Db_lto=true \ - -Dmbim_qmux=$(if $(CONFIG_LIBQMI_WITH_MBIM_QMUX),true,false) \ - -Dqrtr=$(if $(CONFIG_LIBQMI_WITH_QRTR_GLIB),true,false) \ - -Dcollection=$(if $(CONFIG_LIBQMI_COLLECTION_MINIMAL),minimal\ - ,$(if $(CONFIG_LIBQMI_COLLECTION_BASIC),basic,full)) - -define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include - $(CP) \ - $(PKG_INSTALL_DIR)/usr/include/libqmi-glib \ - $(1)/usr/include/ - - $(INSTALL_DIR) $(1)/usr/lib - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libqmi*.so* \ - $(1)/usr/lib/ - - $(INSTALL_DIR) $(1)/usr/lib/pkgconfig - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/qmi-glib.pc \ - $(1)/usr/lib/pkgconfig -endef - -define Package/libqmi/install - $(INSTALL_DIR) \ - $(1)/usr/lib \ - $(1)/usr/libexec - - $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libqmi*.so.* \ - $(1)/usr/lib/ - - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/libexec/qmi-proxy $(1)/usr/libexec/ -endef - -define Package/qmi-utils/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmicli $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmi-network $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmi-firmware-update $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,libqmi)) -$(eval $(call BuildPackage,qmi-utils)) diff --git a/luci-app-cpufreq/Makefile b/luci-app-cpufreq/Makefile deleted file mode 100755 index b85e91d22..000000000 --- a/luci-app-cpufreq/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-only -# -# Copyright (C) 2021 ImmortalWrt.org - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=LuCI for CPU Freq Setting -LUCI_DEPENDS:=@(arm||aarch64) - -PKG_NAME:=luci-app-cpufreq -PKG_VERSION:=1 -PKG_RELEASE:=$(COMMITCOUNT) - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-cpufreq/luasrc/controller/cpufreq.lua b/luci-app-cpufreq/luasrc/controller/cpufreq.lua deleted file mode 100755 index 2bf7a5686..000000000 --- a/luci-app-cpufreq/luasrc/controller/cpufreq.lua +++ /dev/null @@ -1,11 +0,0 @@ -module("luci.controller.cpufreq", package.seeall) - -function index() - if not nixio.fs.access("/etc/config/cpufreq") then - return - end - - local page = entry({"admin", "system", "cpufreq"}, cbi("cpufreq"), _("CPU Freq"), 90) - page.dependent = false - page.acl_depends = { "luci-app-cpufreq" } -end diff --git a/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua b/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua deleted file mode 100755 index febb7ad90..000000000 --- a/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua +++ /dev/null @@ -1,68 +0,0 @@ -local fs = require "nixio.fs" - -function string.split(input, delimiter) - input = tostring(input) - delimiter = tostring(delimiter) - if (delimiter=='') then return false end - local pos,arr = 0, {} - for st,sp in function() return string.find(input, delimiter, pos, true) end do - table.insert(arr, string.sub(input, pos, st - 1)) - pos = sp + 1 - end - table.insert(arr, string.sub(input, pos)) - return arr -end - -mp = Map("cpufreq", translate("CPU Freq Settings")) -mp.description = translate("Set CPU Scaling Governor to Max Performance or Balance Mode") - -s = mp:section(NamedSection, "cpufreq", "settings") -s.anonymouse = true - -local policy_nums = luci.sys.exec("echo -n $(find /sys/devices/system/cpu/cpufreq/policy* -maxdepth 0 | grep -Eo '[0-9]+')") -for _, policy_num in ipairs(string.split(policy_nums, " ")) do - if not fs.access("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_frequencies") then return end - - cpu_freqs = fs.readfile("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_frequencies") - cpu_freqs = string.sub(cpu_freqs, 1, -3) - - cpu_governors = fs.readfile("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_governors") - cpu_governors = string.sub(cpu_governors, 1, -3) - - - freq_array = string.split(cpu_freqs, " ") - governor_array = string.split(cpu_governors, " ") - - s:tab(policy_num, translate("Policy " .. policy_num)) - - governor = s:taboption(policy_num, ListValue, "governor" .. policy_num, translate("CPU Scaling Governor")) - for _, e in ipairs(governor_array) do - if e ~= "" then governor:value(e, translate(e, string.upper(e))) end - end - - minfreq = s:taboption(policy_num, ListValue, "minfreq" .. policy_num, translate("Min Idle CPU Freq")) - for _, e in ipairs(freq_array) do - if e ~= "" then minfreq:value(e) end - end - - maxfreq = s:taboption(policy_num, ListValue, "maxfreq" .. policy_num, translate("Max Turbo Boost CPU Freq")) - for _, e in ipairs(freq_array) do - if e ~= "" then maxfreq:value(e) end - end - - sdfactor = s:taboption(policy_num, Value, "sdfactor" .. policy_num, translate("CPU Switching Sampling rate")) - sdfactor.datatype="range(1,100000)" - sdfactor.description = translate("The sampling rate determines how frequently the governor checks to tune the CPU (ms)") - sdfactor.placeholder = 10 - sdfactor.default = 10 - sdfactor:depends("governor" .. policy_num, "ondemand") - - upthreshold = s:taboption(policy_num, Value, "upthreshold" .. policy_num, translate("CPU Switching Threshold")) - upthreshold.datatype="range(1,99)" - upthreshold.description = translate("Kernel make a decision on whether it should increase the frequency (%)") - upthreshold.placeholder = 50 - upthreshold.default = 50 - upthreshold:depends("governor" .. policy_num, "ondemand") -end - -return mp diff --git a/luci-app-cpufreq/po/zh-cn/cpufreq.po b/luci-app-cpufreq/po/zh-cn/cpufreq.po deleted file mode 100755 index bd818d774..000000000 --- a/luci-app-cpufreq/po/zh-cn/cpufreq.po +++ /dev/null @@ -1,32 +0,0 @@ -msgid "CPU Freq" -msgstr "CPU 性能优化调节" - -msgid "CPU Freq Settings" -msgstr "CPU 性能优化调节设置" - -msgid "Set CPU Scaling Governor to Max Performance or Balance Mode" -msgstr "设置路由器的 CPU 性能模式(高性能/均衡省电)" - -msgid "CPU Scaling Governor" -msgstr "CPU 工作模式" - -msgid "CPU Freq from 48000 to 716000 (Khz)" -msgstr "CPU 频率范围为 48000 到 716000 (Khz)" - -msgid "Min Idle CPU Freq" -msgstr "待机 CPU 最小频率" - -msgid "Max Turbo Boost CPU Freq" -msgstr "最大 Turbo Boost CPU 频率" - -msgid "CPU Switching Sampling rate" -msgstr "CPU 切换周期" - -msgid "The sampling rate determines how frequently the governor checks to tune the CPU (ms)" -msgstr "CPU 检查切换的周期 (ms)。注意:过于频繁的切换频率会引起网络延迟抖动" - -msgid "CPU Switching Threshold" -msgstr "CPU 切换频率触发阈值" - -msgid "Kernel make a decision on whether it should increase the frequency (%)" -msgstr "当 CPU 占用率超过 (%) 的情况下触发内核切换频率" diff --git a/luci-app-cpufreq/root/etc/config/cpufreq b/luci-app-cpufreq/root/etc/config/cpufreq deleted file mode 100755 index 5c2c070e9..000000000 --- a/luci-app-cpufreq/root/etc/config/cpufreq +++ /dev/null @@ -1,3 +0,0 @@ - -config settings 'cpufreq' - diff --git a/luci-app-cpufreq/root/etc/init.d/cpufreq b/luci-app-cpufreq/root/etc/init.d/cpufreq deleted file mode 100755 index 4dda93bc7..000000000 --- a/luci-app-cpufreq/root/etc/init.d/cpufreq +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh /etc/rc.common -START=15 - -NAME="cpufreq" - -config_get_cpufreq() -{ - config_get "$NAME" "$1" -} - -start() -{ - config_load "$NAME" - - for i in $(find /sys/devices/system/cpu/cpufreq/policy* -maxdepth 0 | grep -Eo '[0-9]+') - do - [ -z "$(config_get_cpufreq "governor$i")" ] && return - - config_get_cpufreq "governor$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_governor" - config_get_cpufreq "minfreq$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_min_freq" - config_get_cpufreq "maxfreq$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_max_freq" - if [ "$(config_get_cpufreq "governor$i")" = "ondemand" ]; then - config_get_cpufreq "sdfactor$i" > "/sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor" - config_get_cpufreq "upthreshold$i" > "/sys/devices/system/cpu/cpufreq/ondemand/up_threshold" - fi - done -} diff --git a/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq b/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq deleted file mode 100755 index 4ad31dd5f..000000000 --- a/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh - -uci_write_config() { - uci -q set cpufreq.cpufreq.governor$1="$2" - uci -q set cpufreq.cpufreq.minfreq$1="$3" - uci -q set cpufreq.cpufreq.maxfreq$1="$4" - [ -n "$5" ] && uci -q set cpufreq.cpufreq.sdfactor$1="$5" - [ -n "$6" ] && uci -q set cpufreq.cpufreq.upthreshold$1="$6" - uci -q commit cpufreq -} - -CPU_FREQS="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies')" -CPU_POLICYS="$(find '/sys/devices/system/cpu/cpufreq/policy'* -maxdepth 0 | grep -Eo '[0-9]+')" -source "/etc/openwrt_release" -case "$DISTRIB_TARGET" in - "bcm27xx/bcm2710") - uci_write_config 0 ondemand 600000 1200000 10 50 - ;; - "bcm27xx/bcm2711") - uci_write_config 0 ondemand 600000 1500000 10 50 - ;; - "ipq40xx/generic") - uci_write_config 0 ondemand 200000 716000 10 50 - ;; - "ipq60xx/generic") - if echo "$CPU_FREQS" | grep -q "1800000"; then - # IPQ6010/18/28 - CPU_MAX_FREQ="1800000" - else - # IPQ6000 - CPU_MAX_FREQ="1200000" - fi - uci_write_config 0 ondemand 864000 $CPU_MAX_FREQ 10 50 - ;; - "ipq806x/generic") - if echo "$CPU_FREQS" | grep -q "1725000"; then - # IPQ8065 - CPU_MAX_FREQ="1725000" - elif echo "$CPU_FREQS" | grep -q "1400000"; then - # IPQ8064 - CPU_MAX_FREQ="1400000" - else - # IPQ8062 - CPU_MAX_FREQ="1000000" - fi - uci_write_config 0 ondemand 600000 $CPU_MAX_FREQ 10 50 - # IPQ8064/5 - echo "$CPU_POLICYS" | grep -q "1" && uci_write_config 1 ondemand 600000 1200000 10 50 - ;; - "ipq807x/generic") - if echo "$CPU_FREQS" | grep -q "2208000"; then - # IPQ8072/4/6/8A - CPU_MAX_FREQ="2208000" - else - # IPQ8071A - CPU_MAX_FREQ="1382400" - fi - uci_write_config 0 ondemand 1017600 $CPU_MAX_FREQ 10 50 - ;; - "mediatek/mt7622") - uci_write_config 0 ondemand 600000 1350000 10 50 - ;; - "meson/meson8b") - uci_write_config 0 schedutil 816000 1536000 - ;; - "rockchip/armv8") - if echo "$CPU_POLICYS" | grep -q "4"; then - # RK3399 - uci_write_config 0 schedutil 600000 1608000 - uci_write_config 4 schedutil 600000 2016000 - else - if echo "$CPU_FREQS" | grep -q "1992000"; then - # RK3568 - CPU_MAX_FREQ="1992000" - elif echo "$CPU_FREQS" | grep -q "1800000"; then - # RK3566 - CPU_MAX_FREQ="1800000" - else - # RK3328 - CPU_MAX_FREQ="1512000" - fi - uci_write_config 0 schedutil 816000 $CPU_MAX_FREQ - fi - ;; - "sunxi/cortexa53") - if echo "$CPU_FREQS" | grep -q "1800000"; then - # H6 - uci_write_config 0 schedutil 816000 1800000 - else - # H5 - uci_write_config 0 ondemand 648000 1200000 10 50 - fi - ;; -esac - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@cpufreq[-1] - add ucitrack cpufreq - set ucitrack.@cpufreq[-1].init=cpufreq - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json b/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json deleted file mode 100755 index fae58ae40..000000000 --- a/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-cpufreq": { - "description": "Grant UCI access for luci-app-cpufreq", - "read": { - "uci": [ "cpufreq" ] - }, - "write": { - "uci": [ "cpufreq" ] - } - } -} diff --git a/luci-app-diskman/Makefile b/luci-app-diskman/Makefile deleted file mode 100755 index fa6c46357..000000000 --- a/luci-app-diskman/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-diskman - -PKG_MAINTAINER:=lisaac -PKG_LICENSE:=AGPL-3.0 - -LUCI_TITLE:=Disk Manager interface for LuCI -LUCI_DEPENDS:=+blkid +e2fsprogs +parted +smartmontools \ - +PACKAGE_$(PKG_NAME)_INCLUDE_btrfs_progs:btrfs-progs \ - +PACKAGE_$(PKG_NAME)_INCLUDE_lsblk:lsblk \ - +PACKAGE_$(PKG_NAME)_INCLUDE_mdadm:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456:kmod-md-raid456 \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linears:mdadm \ - +PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linears:kmod-md-linear - -include $(INCLUDE_DIR)/package.mk - -define Package/$(PKG_NAME)/config -config PACKAGE_$(PKG_NAME)_INCLUDE_btrfs_progs - bool "Include btrfs-progs" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_lsblk - bool "Include lsblk" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include mdadm" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_raid456 - depends on PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include kmod-md-raid456" - default n - -config PACKAGE_$(PKG_NAME)_INCLUDE_kmod_md_linear - depends on PACKAGE_$(PKG_NAME)_INCLUDE_mdadm - bool "Include kmod-md-linear" - default n -endef - -define Package/$(PKG_NAME)/postinst -#!/bin/sh -rm -fr /tmp/luci-indexcache /tmp/luci-modulecache -endef - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-diskman/luasrc/controller/diskman.lua b/luci-app-diskman/luasrc/controller/diskman.lua deleted file mode 100755 index 258120430..000000000 --- a/luci-app-diskman/luasrc/controller/diskman.lua +++ /dev/null @@ -1,155 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -module("luci.controller.diskman",package.seeall) - -function index() - -- check all used executables in disk management are existed - local CMD = {"parted", "blkid", "smartctl"} - local executables_all_existed = true - for _, cmd in ipairs(CMD) do - local command = luci.sys.exec("/usr/bin/which " .. cmd) - if not command:match(cmd) then - executables_all_existed = false - break - end - end - - if not executables_all_existed then return end - -- entry(path, target, title, order) - -- set leaf attr to true to pass argument throughe url (e.g. admin/system/disk/partition/sda) - entry({"admin", "system", "diskman"}, alias("admin", "system", "diskman", "disks"), _("Disk Man"), 55) - entry({"admin", "system", "diskman", "disks"}, form("diskman/disks"), nil).leaf = true - entry({"admin", "system", "diskman", "partition"}, form("diskman/partition"), nil).leaf = true - entry({"admin", "system", "diskman", "btrfs"}, form("diskman/btrfs"), nil).leaf = true - entry({"admin", "system", "diskman", "format_partition"}, call("format_partition"), nil).leaf = true - entry({"admin", "system", "diskman", "get_disk_info"}, call("get_disk_info"), nil).leaf = true - entry({"admin", "system", "diskman", "mk_p_table"}, call("mk_p_table"), nil).leaf = true - entry({"admin", "system", "diskman", "smartdetail"}, call("smart_detail"), nil).leaf = true - entry({"admin", "system", "diskman", "smartattr"}, call("smart_attr"), nil).leaf = true -end - -function format_partition() - local partation_name = luci.http.formvalue("partation_name") - local fs = luci.http.formvalue("file_system") - if not partation_name then - luci.http.status(500, "Partition NOT found!") - luci.http.write_json("Partition NOT found!") - return - elseif not nixio.fs.access("/dev/"..partation_name) then - luci.http.status(500, "Partition NOT found!") - luci.http.write_json("Partition NOT found!") - return - elseif not fs then - luci.http.status(500, "no file system") - luci.http.write_json("no file system") - return - end - local dm = require "luci.model.diskman" - code, msg = dm.format_partition(partation_name, fs) - luci.http.status(code, msg) - luci.http.write_json(msg) -end - -function get_disk_info(dev) - if not dev then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - elseif not nixio.fs.access("/dev/"..dev) then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - end - local dm = require "luci.model.diskman" - local device_info = dm.get_disk_info(dev) - luci.http.status(200, "ok") - luci.http.prepare_content("application/json") - luci.http.write_json(device_info) -end - -function mk_p_table() - local p_table = luci.http.formvalue("p_table") - local dev = luci.http.formvalue("dev") - if not dev then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - elseif not nixio.fs.access("/dev/"..dev) then - luci.http.status(500, "no device") - luci.http.write_json("no device") - return - end - local dm = require "luci.model.diskman" - if p_table == "GPT" or p_table == "MBR" then - p_table = p_table == "MBR" and "msdos" or "gpt" - local res = luci.sys.call(dm.command.parted .. " -s /dev/" .. dev .. " mktable ".. p_table) - if res == 0 then - luci.http.status(200, "ok") - else - luci.http.status(500, "command exec error") - end - luci.http.prepare_content("application/json") - luci.http.write_json({code=res}) - else - luci.http.status(404, "not support") - luci.http.prepare_content("application/json") - luci.http.write_json({code="1"}) - end -end - -function smart_detail(dev) - luci.template.render("diskman/smart_detail", {dev=dev}) -end - -function smart_attr(dev) - local dm = require "luci.model.diskman" - local cmd = io.popen(dm.command.smartctl .. " -H -A -i /dev/%s" % dev) - if cmd then - local attr = { } - if cmd:match("NVMe Version:")then - while true do - local ln = cmd:read("*l") - if not ln then - break - elseif ln:match("^(.-):%s+(.+)") then - local key, value = ln:match("^(.-):%s+(.+)") - attr[#attr+1]= { - key = key, - value = value - } - end - end - else - while true do - local ln = cmd:read("*l") - if not ln then - break - elseif ln:match("^.*%d+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+%s+.+") then - local id,attrbute,flag,value,worst,thresh,type,updated,raw = ln:match("^%s*(%d+)%s+([%a%p]+)%s+(%w+)%s+(%d+)%s+(%d+)%s+(%d+)%s+([%a%p]+)%s+(%a+)%s+[%w%p]+%s+(.+)") - id= "%x" % id - if not id:match("^%w%w") then - id = "0%s" % id - end - attr[#attr+1]= { - id = id:upper(), - attrbute = attrbute, - flag = flag, - value = value, - worst = worst, - thresh = thresh, - type = type, - updated = updated, - raw = raw - } - end - end - end - cmd:close() - luci.http.prepare_content("application/json") - luci.http.write_json(attr) - end -end diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua b/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua deleted file mode 100755 index 006007853..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/btrfs.lua +++ /dev/null @@ -1,210 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" -local uuid = arg[1] - -if not uuid then luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) end - --- mount subv=/ to tempfs -mount_point = "/tmp/.btrfs_tmp" -nixio.fs.mkdirr(mount_point) -luci.util.exec(dm.command.umount .. " "..mount_point .. " >/dev/null 2>&1") -luci.util.exec(dm.command.mount .. " -t btrfs -o subvol=/ UUID="..uuid.." "..mount_point) - -m = SimpleForm("btrfs", translate("Btrfs"), translate("Manage Btrfs")) -m.template = "diskman/cbi/xsimpleform" -m.redirect = luci.dispatcher.build_url("admin/system/diskman") -m.submit = false -m.reset = false - --- info -local btrfs_info = dm.get_btrfs_info(mount_point) -local table_btrfs_info = m:section(Table, {btrfs_info}, translate("Btrfs Info")) -table_btrfs_info:option(DummyValue, "uuid", translate("UUID")) -table_btrfs_info:option(DummyValue, "members", translate("Members")) -table_btrfs_info:option(DummyValue, "data_raid_level", translate("Data")) -table_btrfs_info:option(DummyValue, "metadata_raid_lavel", translate("Metadata")) -table_btrfs_info:option(DummyValue, "size_formated", translate("Size")) -table_btrfs_info:option(DummyValue, "used_formated", translate("Used")) -table_btrfs_info:option(DummyValue, "free_formated", translate("Free Space")) -table_btrfs_info:option(DummyValue, "usage", translate("Usage")) -local v_btrfs_label = table_btrfs_info:option(Value, "label", translate("Label")) -local value_btrfs_label = "" -v_btrfs_label.write = function(self, section, value) - value_btrfs_label = value or "" -end -local btn_update_label = table_btrfs_info:option(Button, "_update_label") -btn_update_label.inputtitle = translate("Update") -btn_update_label.inputstyle = "edit" -btn_update_label.write = function(self, section, value) - local cmd = dm.command.btrfs .. " filesystem label " .. mount_point .. " " .. value_btrfs_label - local res = luci.util.exec(cmd) - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) -end --- subvolume -local subvolume_list = dm.get_btrfs_subv(mount_point) -subvolume_list["_"] = { ID = 0 } -table_subvolume = m:section(Table, subvolume_list, translate("SubVolumes")) -table_subvolume:option(DummyValue, "id", translate("ID")) -table_subvolume:option(DummyValue, "top_level", translate("Top Level")) -table_subvolume:option(DummyValue, "uuid", translate("UUID")) -table_subvolume:option(DummyValue, "otime", translate("Otime")) -table_subvolume:option(DummyValue, "snapshots", translate("Snapshots")) -local v_path = table_subvolume:option(Value, "path", translate("Path")) -v_path.forcewrite = true -v_path.render = function(self, section, scope) - if subvolume_list[section].ID == 0 then - self.template = "cbi/value" - self.placeholder = "/my_subvolume" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -local value_path -v_path.write = function(self, section, value) - value_path = value -end -local btn_set_default = table_subvolume:option(Button, "_subv_set_default", translate("Set Default")) -btn_set_default.forcewrite = true -btn_set_default.inputstyle = "edit" -btn_set_default.template = "diskman/cbi/disabled_button" -btn_set_default.render = function(self, section, scope) - if subvolume_list[section].default_subvolume then - self.view_disabled = true - self.inputtitle = translate("Set Default") - elseif subvolume_list[section].ID == 0 then - self.template = "cbi/dvalue" - else - self.inputtitle = translate("Set Default") - self.view_disabled = false - end - Button.render(self, section, scope) -end -btn_set_default.write = function(self, section, value) - local cmd - if value == translate("Set Default") then - cmd = dm.command.btrfs .. " subvolume set-default " .. mount_point..subvolume_list[section].path - else - cmd = dm.command.btrfs .. " subvolume set-default " .. mount_point.."/" - end - local res = luci.util.exec(cmd.. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = res - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end -end -local btn_remove = table_subvolume:option(Button, "_subv_remove") -btn_remove.template = "diskman/cbi/disabled_button" -btn_remove.forcewrite = true -btn_remove.render = function(self, section, scope) - if subvolume_list[section].ID == 0 then - btn_remove.inputtitle = translate("Create") - btn_remove.inputstyle = "add" - self.view_disabled = false - elseif subvolume_list[section].path == "/" or subvolume_list[section].default_subvolume then - btn_remove.inputtitle = translate("Delete") - btn_remove.inputstyle = "remove" - self.view_disabled = true - else - btn_remove.inputtitle = translate("Delete") - btn_remove.inputstyle = "remove" - self.view_disabled = false - end - Button.render(self, section, scope) -end - -btn_remove.write = function(self, section, value) - local cmd - if value == translate("Delete") then - cmd = dm.command.btrfs .. " subvolume delete " .. mount_point .. subvolume_list[section].path - elseif value == translate("Create") then - if value_path and value_path:match("^/") then - cmd = dm.command.btrfs .. " subvolume create " .. mount_point .. value_path - else - m.errmessage = translate("Please input Subvolume Path, Subvolume must start with '/'") - return - end - end - local res = luci.util.exec(cmd.. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end -end --- snapshot --- local snapshot_list = dm.get_btrfs_subv(mount_point, 1) --- table_snapshot = m:section(Table, snapshot_list, translate("Snapshots")) --- table_snapshot:option(DummyValue, "id", translate("ID")) --- table_snapshot:option(DummyValue, "top_level", translate("Top Level")) --- table_snapshot:option(DummyValue, "uuid", translate("UUID")) --- table_snapshot:option(DummyValue, "otime", translate("Otime")) --- table_snapshot:option(DummyValue, "path", translate("Path")) --- local snp_remove = table_snapshot:option(Button, "_snp_remove") --- snp_remove.inputtitle = translate("Delete") --- snp_remove.inputstyle = "remove" --- snp_remove.write = function(self, section, value) --- local cmd = dm.command.btrfs .. " subvolume delete " .. mount_point .. snapshot_list[section].path --- local res = luci.util.exec(cmd.. " 2>&1") --- if res and (res:match("ERR") or res:match("not enough arguments")) then --- m.errmessage = luci.util.pcdata(res) --- else --- luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) --- end --- end - --- new snapshots -local s_snapshot = m:section(SimpleSection, translate("New Snapshot")) -local value_sorce, value_dest, value_readonly -local v_sorce = s_snapshot:option(Value, "_source", translate("Source Path"), translate("The source path for create the snapshot")) -v_sorce.placeholder = "/data" -v_sorce.forcewrite = true -v_sorce.write = function(self, section, value) - value_sorce = value -end - -local v_readonly = s_snapshot:option(Flag, "_readonly", translate("Readonly"), translate("The path where you want to store the snapshot")) -v_readonly.forcewrite = true -v_readonly.rmempty = false -v_readonly.disabled = 0 -v_readonly.enabled = 1 -v_readonly.default = 1 -v_readonly.write = function(self, section, value) - value_readonly = value -end -local v_dest = s_snapshot:option(Value, "_dest", translate("Destination Path (optional)")) -v_dest.forcewrite = true -v_dest.placeholder = "/.snapshot/202002051538" -v_dest.write = function(self, section, value) - value_dest = value -end -local btn_snp_create = s_snapshot:option(Button, "_snp_create") -btn_snp_create.title = " " -btn_snp_create.inputtitle = translate("New Snapshot") -btn_snp_create.inputstyle = "add" -btn_snp_create.write = function(self, section, value) - if value_sorce and value_sorce:match("^/") then - if not value_dest then value_dest = "/.snapshot"..value_sorce.."/"..os.date("%Y%m%d%H%M%S") end - nixio.fs.mkdirr(mount_point..value_dest:match("(.-)[^/]+$")) - local cmd = dm.command.btrfs .. " subvolume snapshot" .. (value_readonly == 1 and " -r " or " ") .. mount_point..value_sorce .. " " .. mount_point..value_dest - local res = luci.util.exec(cmd .. " 2>&1") - if res and (res:match("ERR") or res:match("not enough arguments")) then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/btrfs/" .. uuid)) - end - else - m.errmessage = translate("Please input Source Path of snapshot, Source Path must start with '/'") - end -end - -return m diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua b/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua deleted file mode 100755 index c209df0aa..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/disks.lua +++ /dev/null @@ -1,327 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" - --- Use (non-UCI) SimpleForm since we have no related config file -m = SimpleForm("diskman", translate("DiskMan"), translate("Manage Disks over LuCI.")) -m.template = "diskman/cbi/xsimpleform" -m:append(Template("diskman/disk_info")) --- disable submit and reset button -m.submit = false -m.reset = false --- rescan disks -rescan = m:section(SimpleSection) -rescan_button = rescan:option(Button, "_rescan") -rescan_button.inputtitle= translate("Rescan Disks") -rescan_button.template = "diskman/cbi/inlinebutton" -rescan_button.inputstyle = "add" -rescan_button.forcewrite = true -rescan_button.write = function(self, section, value) - luci.util.exec("echo '- - -' | tee /sys/class/scsi_host/host*/scan > /dev/null") - if dm.command.mdadm then - luci.util.exec(dm.command.mdadm .. " --assemble --scan") - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end - --- disks -local disks = dm.list_devices() -d = m:section(Table, disks, translate("Disks")) -d.config = "disk" --- option(type, id(key of table), text) -d:option(DummyValue, "path", translate("Path")) -d:option(DummyValue, "model", translate("Model")) -d:option(DummyValue, "sn", translate("Serial Number")) -d:option(DummyValue, "size_formated", translate("Size")) -d:option(DummyValue, "temp", translate("Temp")) --- d:option(DummyValue, "sec_size", translate("Sector Size ")) -d:option(DummyValue, "p_table", translate("Partition Table")) -d:option(DummyValue, "sata_ver", translate("SATA Version")) --- d:option(DummyValue, "rota_rate", translate("Rotation Rate")) -d:option(DummyValue, "health", translate("Health")) -d:option(DummyValue, "status", translate("Status")) - -d.extedit = luci.dispatcher.build_url("admin/system/diskman/partition/%s") - --- raid devices -if dm.command.mdadm then - local raid_devices = dm.list_raid_devices() - -- raid_devices = diskmanager.getRAIDdevices() - if next(raid_devices) ~= nil then - local r = m:section(Table, raid_devices, translate("RAID Devices")) - r.config = "_raid" - r:option(DummyValue, "path", translate("Path")) - r:option(DummyValue, "level", translate("RAID mode")) - r:option(DummyValue, "size_formated", translate("Size")) - r:option(DummyValue, "p_table", translate("Partition Table")) - r:option(DummyValue, "status", translate("Status")) - r:option(DummyValue, "members_str", translate("Members")) - r:option(DummyValue, "active", translate("Active")) - r.extedit = luci.dispatcher.build_url("admin/system/diskman/partition/%s") - end -end - --- btrfs devices -if dm.command.btrfs then - btrfs_devices = dm.list_btrfs_devices() - if next(btrfs_devices) ~= nil then - local table_btrfs = m:section(Table, btrfs_devices, translate("Btrfs")) - table_btrfs:option(DummyValue, "uuid", translate("UUID")) - table_btrfs:option(DummyValue, "label", translate("Label")) - table_btrfs:option(DummyValue, "members", translate("Members")) - -- sieze is error, since there is RAID - -- table_btrfs:option(DummyValue, "size_formated", translate("Size")) - table_btrfs:option(DummyValue, "used_formated", translate("Usage")) - table_btrfs.extedit = luci.dispatcher.build_url("admin/system/diskman/btrfs/%s") - end -end - --- mount point -local mount_point = dm.get_mount_points() -local _mount_point = {} -table.insert( mount_point, { device = 0 } ) -local table_mp = m:section(Table, mount_point, translate("Mount Point")) -local v_device = table_mp:option(Value, "device", translate("Device")) -v_device.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.forcewrite = true - for dev, info in pairs(disks) do - for i, v in ipairs(info.partitions) do - self:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -v_device.write = function(self, section, value) - _mount_point.device = value and value:gsub("%s+", "") or "" -end -local v_fs = table_mp:option(Value, "fs", translate("File System")) -v_fs.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self:value("auto", "auto") - self.default = "auto" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -v_fs.write = function(self, section, value) - _mount_point.fs = value and value:gsub("%s+", "") or "" -end -local v_mount_option = table_mp:option(Value, "mount_options", translate("Mount Options")) -v_mount_option.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.placeholder = "rw,noauto" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - local mp = mount_point[section].mount_options - mount_point[section].mount_options = nil - local length = 0 - for k in mp:gmatch("([^,]+)") do - mount_point[section].mount_options = mount_point[section].mount_options and (mount_point[section].mount_options .. ",") or "" - if length > 20 then - mount_point[section].mount_options = mount_point[section].mount_options.. "
" - length = 0 - end - mount_point[section].mount_options = mount_point[section].mount_options .. k - length = length + #k - end - self.rawhtml = true - -- mount_point[section].mount_options = #mount_point[section].mount_options > 50 and mount_point[section].mount_options:sub(1,50) .. "..." or mount_point[section].mount_options - DummyValue.render(self, section, scope) - end -end -v_mount_option.write = function(self, section, value) - _mount_point.mount_options = value and value:gsub("%s+", "") or "" -end -local v_mount_point = table_mp:option(Value, "mount_point", translate("Mount Point")) -v_mount_point.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.template = "cbi/value" - self.placeholder = "/media/diskX" - self.forcewrite = true - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - local new_mp = "" - local v_mp_d - for v_mp_d in self["section"]["data"][section]["mount_point"]:gmatch('[^/]+') do - if #v_mp_d > 12 then - new_mp = new_mp .. "/" .. v_mp_d:sub(1,7) .. ".." .. v_mp_d:sub(-4) - else - new_mp = new_mp .."/".. v_mp_d - end - end - self["section"]["data"][section]["mount_point"] = ''..new_mp..'' - self.rawhtml = true - DummyValue.render(self, section, scope) - end -end -v_mount_point.write = function(self, section, value) - _mount_point.mount_point = value -end -local btn_umount = table_mp:option(Button, "_mount", translate("Mount")) -btn_umount.forcewrite = true -btn_umount.render = function(self, section, scope) - if mount_point[section].device == 0 then - self.inputtitle = translate("Mount") - btn_umount.inputstyle = "add" - else - self.inputtitle = translate("Umount") - btn_umount.inputstyle = "remove" - end - Button.render(self, section, scope) -end -btn_umount.write = function(self, section, value) - local res - if value == translate("Mount") then - if not _mount_point.mount_point or not _mount_point.device then return end - luci.util.exec("mkdir -p ".. _mount_point.mount_point) - res = luci.util.exec(dm.command.mount .. " ".. _mount_point.device .. (_mount_point.fs and (" -t ".. _mount_point.fs )or "") .. (_mount_point.mount_options and (" -o " .. _mount_point.mount_options.. " ") or " ").._mount_point.mount_point .. " 2>&1") - elseif value == translate("Umount") then - res = luci.util.exec(dm.command.umount .. " "..mount_point[section].mount_point .. " 2>&1") - end - if res:match("^mount:") or res:match("^umount:") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end - -if dm.command.mdadm or dm.command.btrfs then -local creation_section = m:section(TypedSection, "_creation") -creation_section.cfgsections=function() - return {translate("Creation")} -end -creation_section:tab("raid", translate("RAID"), translate("RAID Creation")) -creation_section:tab("btrfs", translate("Btrfs"), translate("Multiple Devices Btrfs Creation")) - --- raid functions -if dm.command.mdadm then - - local rname, rmembers, rlevel - local r_name = creation_section:taboption("raid", Value, "_rname", translate("Raid Name")) - r_name.placeholder = "/dev/md0" - r_name.write = function(self, section, value) - rname = value - end - local r_level = creation_section:taboption("raid", ListValue, "_rlevel", translate("Raid Level")) - local valid_raid = luci.util.exec("lsmod | grep md_mod") - if valid_raid:match("linear") then - r_level:value("linear", "Linear") - end - if valid_raid:match("raid456") then - r_level:value("5", "Raid 5") - r_level:value("6", "Raid 6") - end - if valid_raid:match("raid1") then - r_level:value("1", "Raid 1") - end - if valid_raid:match("raid0") then - r_level:value("0", "Raid 0") - end - if valid_raid:match("raid10") then - r_level:value("10", "Raid 10") - end - r_level.write = function(self, section, value) - rlevel = value - end - local r_member = creation_section:taboption("raid", DynamicList, "_rmember", translate("Raid Member")) - for dev, info in pairs(disks) do - if not info.inuse and #info.partitions == 0 then - r_member:value(info.path, info.path.. " ".. info.size_formated) - end - for i, v in ipairs(info.partitions) do - if not v.inuse then - r_member:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - end - r_member.write = function(self, section, value) - rmembers = value - end - local r_create = creation_section:taboption("raid", Button, "_rcreate") - r_create.render = function(self, section, scope) - self.title = " " - self.inputtitle = translate("Create Raid") - self.inputstyle = "add" - Button.render(self, section, scope) - end - r_create.write = function(self, section, value) - -- mdadm --create --verbose /dev/md0 --level=stripe --raid-devices=2 /dev/sdb6 /dev/sdc5 - local res = dm.create_raid(rname, rlevel, rmembers) - if res and res:match("^ERR") then - m.errmessage = luci.util.pcdata(res) - return - end - dm.gen_mdadm_config() - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end - --- btrfs -if dm.command.btrfs then - local blabel, bmembers, blevel - local btrfs_label = creation_section:taboption("btrfs", Value, "_blabel", translate("Btrfs Label")) - btrfs_label.write = function(self, section, value) - blabel = value - end - local btrfs_level = creation_section:taboption("btrfs", ListValue, "_blevel", translate("Btrfs Raid Level")) - btrfs_level:value("single", "Single") - btrfs_level:value("raid0", "Raid 0") - btrfs_level:value("raid1", "Raid 1") - btrfs_level:value("raid10", "Raid 10") - btrfs_level.write = function(self, section, value) - blevel = value - end - - local btrfs_member = creation_section:taboption("btrfs", DynamicList, "_bmember", translate("Btrfs Member")) - for dev, info in pairs(disks) do - if not info.inuse and #info.partitions == 0 then - btrfs_member:value(info.path, info.path.. " ".. info.size_formated) - end - for i, v in ipairs(info.partitions) do - if not v.inuse then - btrfs_member:value("/dev/".. v.name, "/dev/".. v.name .. " ".. v.size_formated) - end - end - end - btrfs_member.write = function(self, section, value) - bmembers = value - end - local btrfs_create = creation_section:taboption("btrfs", Button, "_bcreate") - btrfs_create.render = function(self, section, scope) - self.title = " " - self.inputtitle = translate("Create Btrfs") - self.inputstyle = "add" - Button.render(self, section, scope) - end - btrfs_create.write = function(self, section, value) - -- mkfs.btrfs -L label -d blevel /dev/sda /dev/sdb - local res = dm.create_btrfs(blabel, blevel, bmembers) - if res and res:match("^ERR") then - m.errmessage = luci.util.pcdata(res) - return - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) - end -end -end - -return m diff --git a/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua b/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua deleted file mode 100755 index 1428eb6b2..000000000 --- a/luci-app-diskman/luasrc/model/cbi/diskman/partition.lua +++ /dev/null @@ -1,366 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -require("luci.tools.webadmin") -local dm = require "luci.model.diskman" -local dev = arg[1] - -if not dev then - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -elseif not nixio.fs.access("/dev/"..dev) then - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end - -m = SimpleForm("partition", translate("Partition Management"), translate("Partition Disk over LuCI.")) -m.template = "diskman/cbi/xsimpleform" -m.redirect = luci.dispatcher.build_url("admin/system/diskman") -m:append(Template("diskman/partition_info")) --- disable submit and reset button -m.submit = false -m.reset = false - -local disk_info = dm.get_disk_info(dev, true) -local format_cmd = dm.get_format_cmd() - -s = m:section(Table, {disk_info}, translate("Device Info")) --- s:option(DummyValue, "key") --- s:option(DummyValue, "value") -s:option(DummyValue, "path", translate("Path")) -s:option(DummyValue, "model", translate("Model")) -s:option(DummyValue, "sn", translate("Serial Number")) -s:option(DummyValue, "size_formated", translate("Size")) -s:option(DummyValue, "sec_size", translate("Sector Size")) -local dv_p_table = s:option(ListValue, "p_table", translate("Partition Table")) -dv_p_table.render = function(self, section, scope) - -- create table only if not used by raid and no partitions on disk - if not disk_info.p_table:match("Raid") and (#disk_info.partitions == 0 or (#disk_info.partitions == 1 and disk_info.partitions[1].number == -1) or (disk_info.p_table:match("LOOP") and not disk_info.partitions[1].inuse)) then - self:value(disk_info.p_table, disk_info.p_table) - self:value("GPT", "GPT") - self:value("MBR", "MBR") - self.default = disk_info.p_table - ListValue.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end -if disk_info.type:match("md") then - s:option(DummyValue, "level", translate("Level")) - s:option(DummyValue, "members_str", translate("Members")) -else - s:option(DummyValue, "temp", translate("Temp")) - s:option(DummyValue, "sata_ver", translate("SATA Version")) - s:option(DummyValue, "rota_rate", translate("Rotation Rate")) -end -s:option(DummyValue, "status", translate("Status")) -local btn_health = s:option(Button, "health", translate("Health")) -btn_health.render = function(self, section, scope) - if disk_info.health then - self.inputtitle = disk_info.health - if disk_info.health == "PASSED" then - self.inputstyle = "add" - else - self.inputstyle = "remove" - end - Button.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end -end - -local btn_eject = s:option(Button, "_eject") -btn_eject.template = "diskman/cbi/disabled_button" -btn_eject.inputstyle = "remove" -btn_eject.render = function(self, section, scope) - for i, p in ipairs(disk_info.partitions) do - if p.mount_point ~= "-" then - self.view_disabled = true - break - end - end - if disk_info.p_table:match("Raid") then - self.view_disabled = true - end - if disk_info.type:match("md") then - btn_eject.inputtitle = translate("Remove") - else - btn_eject.inputtitle = translate("Eject") - end - Button.render(self, section, scope) -end -btn_eject.forcewrite = true -btn_eject.write = function(self, section, value) - for i, p in ipairs(disk_info.partitions) do - if p.mount_point ~= "-" then - m.errmessage = p.name .. translate("is in use! please unmount it first!") - return - end - end - if disk_info.type:match("md") then - luci.util.exec(dm.command.mdadm .. " --stop /dev/" .. dev) - luci.util.exec(dm.command.mdadm .. " --remove /dev/" .. dev) - for _, disk in ipairs(disk_info.members) do - luci.util.exec(dm.command.mdadm .. " --zero-superblock " .. disk) - end - dm.gen_mdadm_config() - else - luci.util.exec("echo 1 > /sys/block/" .. dev .. "/device/delete") - end - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) -end --- eject: echo 1 > /sys/block/(device)/device/delete --- rescan: echo '- - -' | tee /sys/class/scsi_host/host*/scan > /dev/null - - --- partitions info -if not disk_info.p_table:match("Raid") then - s_partition_table = m:section(Table, disk_info.partitions, translate("Partitions Info"), translate("Default 2048 sector alignment, support +size{b,k,m,g,t} in End Sector")) - - -- s_partition_table:option(DummyValue, "number", translate("Number")) - s_partition_table:option(DummyValue, "name", translate("Name")) - local val_sec_start = s_partition_table:option(Value, "sec_start", translate("Start Sector")) - val_sec_start.render = function(self, section, scope) - -- could create new partition - if disk_info.partitions[section].number == -1 and disk_info.partitions[section].size > 1 * 1024 * 1024 then - self.template = "cbi/value" - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - local val_sec_end = s_partition_table:option(Value, "sec_end", translate("End Sector")) - val_sec_end.render = function(self, section, scope) - -- could create new partition - if disk_info.partitions[section].number == -1 and disk_info.partitions[section].size > 1 * 1024 * 1024 then - self.template = "cbi/value" - Value.render(self, section, scope) - else - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - val_sec_start.forcewrite = true - val_sec_start.write = function(self, section, value) - disk_info.partitions[section]._sec_start = value - end - val_sec_end.forcewrite = true - val_sec_end.write = function(self, section, value) - disk_info.partitions[section]._sec_end = value - end - s_partition_table:option(DummyValue, "size_formated", translate("Size")) - if disk_info.p_table == "MBR" then - s_partition_table:option(DummyValue, "type", translate("Type")) - end - s_partition_table:option(DummyValue, "used_formated", translate("Used")) - s_partition_table:option(DummyValue, "free_formated", translate("Free Space")) - s_partition_table:option(DummyValue, "usage", translate("Usage")) - local dv_mount_point = s_partition_table:option(DummyValue, "mount_point", translate("Mount Point")) - dv_mount_point.rawhtml = true - dv_mount_point.render = function(self, section, scope) - local new_mp = "" - local v_mp_d - for line in self["section"]["data"][section]["mount_point"]:gmatch("[^%s]+") do - if line == '-' then - new_mp = line - break - end - for v_mp_d in line:gmatch('[^/]+') do - if #v_mp_d > 12 then - new_mp = new_mp .. "/" .. v_mp_d:sub(1,7) .. ".." .. v_mp_d:sub(-4) - else - new_mp = new_mp .."/".. v_mp_d - end - end - new_mp = '' ..new_mp ..'' .. "
" - end - self["section"]["data"][section]["mount_point"] = new_mp - DummyValue.render(self, section, scope) - end - local val_fs = s_partition_table:option(Value, "fs", translate("File System")) - val_fs.forcewrite = true - val_fs.partitions = disk_info.partitions - for k, v in pairs(format_cmd) do - val_fs.format_cmd = val_fs.format_cmd and (val_fs.format_cmd .. "," .. k) or k - end - - val_fs.write = function(self, section, value) - disk_info.partitions[section]._fs = value - end - val_fs.render = function(self, section, scope) - -- use listvalue when partition not mounted - if disk_info.partitions[section].mount_point == "-" and disk_info.partitions[section].number ~= -1 and disk_info.partitions[section].type ~= "extended" then - self.template = "diskman/cbi/format_button" - self.inputstyle = "reset" - self.inputtitle = disk_info.partitions[section].fs == "raw" and translate("Format") or disk_info.partitions[section].fs - Button.render(self, section, scope) - -- self:reset_values() - -- self.keylist = {} - -- self.vallist = {} - -- for k, v in pairs(format_cmd) do - -- self:value(k,k) - -- end - -- self.default = disk_info.partitions[section].fs - else - -- self:reset_values() - -- self.keylist = {} - -- self.vallist = {} - self.template = "cbi/dvalue" - DummyValue.render(self, section, scope) - end - end - -- btn_format = s_partition_table:option(Button, "_format") - -- btn_format.template = "diskman/cbi/format_button" - -- btn_format.partitions = disk_info.partitions - -- btn_format.render = function(self, section, scope) - -- if disk_info.partitions[section].mount_point == "-" and disk_info.partitions[section].number ~= -1 and disk_info.partitions[section].type ~= "extended" then - -- self.inputtitle = translate("Format") - -- self.template = "diskman/cbi/disabled_button" - -- self.view_disabled = false - -- self.inputstyle = "reset" - -- for k, v in pairs(format_cmd) do - -- self:depends("val_fs", "k") - -- end - -- -- elseif disk_info.partitions[section].mount_point ~= "-" and disk_info.partitions[section].number ~= -1 then - -- -- self.inputtitle = "Format" - -- -- self.template = "diskman/cbi/disabled_button" - -- -- self.view_disabled = true - -- -- self.inputstyle = "reset" - -- else - -- self.inputtitle = "" - -- self.template = "cbi/dvalue" - -- end - -- Button.render(self, section, scope) - -- end - -- btn_format.forcewrite = true - -- btn_format.write = function(self, section, value) - -- local partition_name = "/dev/".. disk_info.partitions[section].name - -- if not nixio.fs.access(partition_name) then - -- m.errmessage = translate("Partition NOT found!") - -- return - -- end - -- local fs = disk_info.partitions[section]._fs - -- if not format_cmd[fs] then - -- m.errmessage = translate("Filesystem NOT support!") - -- return - -- end - -- local cmd = format_cmd[fs].cmd .. " " .. format_cmd[fs].option .. " " .. partition_name - -- local res = luci.util.exec(cmd .. " 2>&1") - -- if res and res:lower():match("error+") then - -- m.errmessage = luci.util.pcdata(res) - -- else - -- luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - -- end - -- end - - local btn_action = s_partition_table:option(Button, "_action") - btn_action.forcewrite = true - btn_action.template = "diskman/cbi/disabled_button" - btn_action.render = function(self, section, scope) - -- if partition is mounted or the size < 1mb, then disable the add action - if disk_info.partitions[section].mount_point ~= "-" or (disk_info.partitions[section].type ~= "extended" and disk_info.partitions[section].number == -1 and disk_info.partitions[section].size <= 1 * 1024 * 1024) then - self.view_disabled = true - -- self.inputtitle = "" - -- self.template = "cbi/dvalue" - elseif disk_info.partitions[section].type == "extended" and next(disk_info.partitions[section]["logicals"]) ~= nil then - self.view_disabled = true - else - -- self.template = "diskman/cbi/disabled_button" - self.view_disabled = false - end - if disk_info.partitions[section].number ~= -1 then - self.inputtitle = translate("Remove") - self.inputstyle = "remove" - else - self.inputtitle = translate("New") - self.inputstyle = "add" - end - Button.render(self, section, scope) - end - btn_action.write = function(self, section, value) - if value == translate("New") then - local start_sec = disk_info.partitions[section]._sec_start and tonumber(disk_info.partitions[section]._sec_start) or tonumber(disk_info.partitions[section].sec_start) - local end_sec = disk_info.partitions[section]._sec_end - - if start_sec then - -- for sector alignment - local align = tonumber(disk_info.phy_sec) / tonumber(disk_info.logic_sec) - align = (align < 2048) and 2048 - if start_sec < 2048 then - start_sec = "2048" .. "s" - elseif math.fmod( start_sec, align ) ~= 0 then - start_sec = tostring(start_sec + align - math.fmod( start_sec, align )) .. "s" - else - start_sec = start_sec .. "s" - end - else - m.errmessage = translate("Invalid Start Sector!") - return - end - -- support +size format for End sector - local end_size, end_unit = end_sec:match("^+(%d-)([bkmgtsBKMGTS])$") - if tonumber(end_size) and end_unit then - local unit ={ - B=1, - S=512, - K=1024, - M=1048576, - G=1073741824, - T=1099511627776 - } - end_unit = end_unit:upper() - end_sec = tostring(tonumber(end_size) * unit[end_unit] / unit["S"] + tonumber(start_sec:sub(1,-2)) - 1 ) .. "s" - elseif tonumber(end_sec) then - end_sec = end_sec .. "s" - else - m.errmessage = translate("Invalid End Sector!") - return - end - local part_type = "primary" - - if disk_info.p_table == "MBR" and disk_info["extended_partition_index"] then - if tonumber(disk_info.partitions[disk_info["extended_partition_index"]].sec_start) <= tonumber(start_sec:sub(1,-2)) and tonumber(disk_info.partitions[disk_info["extended_partition_index"]].sec_end) >= tonumber(end_sec:sub(1,-2)) then - part_type = "logical" - if tonumber(start_sec:sub(1,-2)) - tonumber(disk_info.partitions[section].sec_start) < 2048 then - start_sec = tonumber(start_sec:sub(1,-2)) + 2048 - start_sec = start_sec .."s" - end - end - elseif disk_info.p_table == "GPT" then - -- AUTOMATIC FIX GPT PARTITION TABLE - -- Not all of the space available to /dev/sdb appears to be used, you can fix the GPT to use all of the space (an extra 16123870 blocks) or continue with the current setting? - local cmd = ' printf "ok\nfix\n" | parted ---pretend-input-tty /dev/'.. dev ..' print' - luci.util.exec(cmd .. " 2>&1") - end - - -- partiton - local cmd = dm.command.parted .. " -s -a optimal /dev/" .. dev .. " mkpart " .. part_type .." " .. start_sec .. " " .. end_sec - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - end - elseif value == translate("Remove") then - -- remove partition - local number = tostring(disk_info.partitions[section].number) - if (not number) or (number == "") then - m.errmessage = translate("Partition not exists!") - return - end - local cmd = dm.command.parted .. " -s /dev/" .. dev .. " rm " .. number - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - m.errmessage = luci.util.pcdata(res) - else - luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman/partition/" .. dev)) - end - end - end -end - -return m diff --git a/luci-app-diskman/luasrc/model/diskman.lua b/luci-app-diskman/luasrc/model/diskman.lua deleted file mode 100755 index b29308c31..000000000 --- a/luci-app-diskman/luasrc/model/diskman.lua +++ /dev/null @@ -1,738 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" -local ver = require "luci.version" - -local CMD = {"parted", "mdadm", "blkid", "smartctl", "df", "btrfs", "lsblk"} - -local d = {command ={}} -for _, cmd in ipairs(CMD) do - local command = luci.sys.exec("/usr/bin/which " .. cmd) - d.command[cmd] = command:match("^.+"..cmd) or nil -end - -d.command.mount = nixio.fs.access("/usr/bin/mount") and "/usr/bin/mount" or "/bin/mount" -d.command.umount = nixio.fs.access("/usr/bin/umount") and "/usr/bin/umount" or "/bin/umount" - -local proc_mounts = nixio.fs.readfile("/proc/mounts") or "" -local mounts = luci.util.exec(d.command.mount .. " 2>/dev/null") or "" -local swaps = nixio.fs.readfile("/proc/swaps") or "" -local df = luci.sys.exec(d.command.df .. " 2>/dev/null") or "" - -function byte_format(byte) - local suff = {"B", "KB", "MB", "GB", "TB"} - for i=1, 5 do - if byte > 1024 and i < 5 then - byte = byte / 1024 - else - return string.format("%.2f %s", byte, suff[i]) - end - end -end - -local get_smart_info = function(device) - local section - local smart_info = {} - for _, line in ipairs(luci.util.execl(d.command.smartctl .. " -H -A -i -n standby -f brief /dev/" .. device)) do - local attrib, val - if section == 1 then - attrib, val = line:match "^(.-):%s+(.+)" - elseif section == 2 and smart_info.nvme_ver then - attrib, val = line:match("^(.-):%s+(.+)") - if not smart_info.health then smart_info.health = line:match(".-overall%-health.-: (.+)") end - elseif section == 2 then - attrib, val = line:match("^([0-9 ]+)%s+[^ ]+%s+[POSRCK-]+%s+[0-9-]+%s+[0-9-]+%s+[0-9-]+%s+[0-9-]+%s+([0-9-]+)") - if not smart_info.health then smart_info.health = line:match(".-overall%-health.-: (.+)") end - else - attrib = line:match "^=== START OF (.*) SECTION ===" - if attrib and attrib:match("INFORMATION") then - section = 1 - elseif attrib and attrib:match("SMART DATA") then - section = 2 - elseif not smart_info.status then - val = line:match "^Device is in (.*) mode" - if val then smart_info.status = val end - end - end - - if not attrib then - if section ~= 2 then section = 0 end - elseif (attrib == "Power mode is") or - (attrib == "Power mode was") then - smart_info.status = val:match("(%S+)") - -- elseif attrib == "Sector Sizes" then - -- -- 512 bytes logical, 4096 bytes physical - -- smart_info.phy_sec = val:match "([0-9]*) bytes physical" - -- smart_info.logic_sec = val:match "([0-9]*) bytes logical" - -- elseif attrib == "Sector Size" then - -- -- 512 bytes logical/physical - -- smart_info.phy_sec = val:match "([0-9]*)" - -- smart_info.logic_sec = smart_info.phy_sec - elseif attrib == "Serial Number" then - smart_info.sn = val - elseif attrib == "194" or attrib == "Temperature" then - smart_info.temp = val:match("(%d+)") .. "°C" - elseif attrib == "Rotation Rate" then - smart_info.rota_rate = val - elseif attrib == "SATA Version is" then - smart_info.sata_ver = val - elseif attrib == "NVMe Version" then - smart_info.nvme_ver = val - end - end - return smart_info -end - -local parse_parted_info = function(keys, line) - -- parse the output of parted command (machine parseable format) - -- /dev/sda:5860533168s:scsi:512:4096:gpt:ATA ST3000DM001-1ER1:; - -- 1:34s:2047s:2014s:free; - -- 1:2048s:1073743872s:1073741825s:ext4:primary:; - local result = {} - local values = {} - - for value in line:gmatch("(.-)[:;]") do table.insert(values, value) end - for i = 1,#keys do - result[keys[i]] = values[i] or "" - end - return result -end - -local is_raid_member = function(partition) - -- check if inuse as raid member - if nixio.fs.access("/proc/mdstat") then - for _, result in ipairs(luci.util.execl("grep md /proc/mdstat | sed 's/[][]//g'")) do - local md, buf - md, buf = result:match("(md.-):(.+)") - if buf:match(partition) then - return "Raid Member: ".. md - end - end - end - return nil -end - -local get_mount_point = function(partition) - local mount_point - for m in mounts:gmatch("/dev/"..partition.." on ([^ ]*)") do - mount_point = (mount_point and (mount_point .. " ") or "") .. m - end - if mount_point then return mount_point end - -- result = luci.sys.exec('cat /proc/mounts | awk \'{if($1=="/dev/'.. partition ..'") print $2}\'') - -- if result ~= "" then return result end - - if swaps:match("\n/dev/" .. partition .."%s") then return "swap" end - -- result = luci.sys.exec("cat /proc/swaps | grep /dev/" .. partition) - -- if result ~= "" then return "swap" end - - return is_raid_member(partition) - -end - --- return used, free, usage -local get_partition_usage = function(partition) - if not nixio.fs.access("/dev/"..partition) then return false end - local used, free, usage = df:match("\n/dev/" .. partition .. "%s+%d+%s+(%d+)%s+(%d+)%s+(%d+)%%%s-") - - usage = usage and (usage .. "%") or "-" - used = used and (tonumber(used) * 1024) or 0 - free = free and (tonumber(free) * 1024) or 0 - - return used, free, usage -end - -local get_parted_info = function(device) - if not device then return end - local result = {partitions={}} - local DEVICE_INFO_KEYS = { "path", "size", "type", "logic_sec", "phy_sec", "p_table", "model", "flags" } - local PARTITION_INFO_KEYS = { "number", "sec_start", "sec_end", "size", "fs", "tag_name", "flags" } - local partition_temp - local partitions_temp = {} - local disk_temp - - for line in luci.util.execi(d.command.parted .. " -s -m /dev/" .. device .. " unit s print free", "r") do - if line:find("^/dev/"..device..":.+") then - disk_temp = parse_parted_info(DEVICE_INFO_KEYS, line) - disk_temp.partitions = {} - if disk_temp["size"] then - local length = disk_temp["size"]:gsub("^(%d+)s$", "%1") - local newsize = tostring(tonumber(length)*tonumber(disk_temp["logic_sec"])) - disk_temp["size"] = newsize - end - if disk_temp["p_table"] == "msdos" then - disk_temp["p_table"] = "MBR" - else - disk_temp["p_table"] = disk_temp["p_table"]:upper() - end - elseif line:find("^%d-:.+") then - partition_temp = parse_parted_info(PARTITION_INFO_KEYS, line) - -- use human-readable form instead of sector number - if partition_temp["size"] then - local length = partition_temp["size"]:gsub("^(%d+)s$", "%1") - local newsize = (tonumber(length) * tonumber(disk_temp["logic_sec"])) - partition_temp["size"] = newsize - partition_temp["size_formated"] = byte_format(newsize) - end - partition_temp["number"] = tonumber(partition_temp["number"]) or -1 - if partition_temp["fs"] == "free" then - partition_temp["number"] = -1 - partition_temp["fs"] = "Free Space" - partition_temp["name"] = "-" - elseif device:match("sd") or device:match("sata") then - partition_temp["name"] = device..partition_temp["number"] - elseif device:match("mmcblk") or device:match("md") or device:match("nvme") then - partition_temp["name"] = device.."p"..partition_temp["number"] - end - if partition_temp["number"] > 0 and partition_temp["fs"] == "" and d.command.lsblk then - partition_temp["fs"] = luci.util.exec(d.command.lsblk .. " /dev/"..device.. tostring(partition_temp["number"]) .. " -no fstype"):match("([^%s]+)") or "" - end - partition_temp["fs"] = partition_temp["fs"] == "" and "raw" or partition_temp["fs"] - partition_temp["sec_start"] = partition_temp["sec_start"] and partition_temp["sec_start"]:sub(1,-2) - partition_temp["sec_end"] = partition_temp["sec_end"] and partition_temp["sec_end"]:sub(1,-2) - partition_temp["mount_point"] = partition_temp["name"]~="-" and get_mount_point(partition_temp["name"]) or "-" - if partition_temp["mount_point"]~="-" then - partition_temp["used"], partition_temp["free"], partition_temp["usage"] = get_partition_usage(partition_temp["name"]) - partition_temp["used_formated"] = partition_temp["used"] and byte_format(partition_temp["used"]) or "-" - partition_temp["free_formated"] = partition_temp["free"] and byte_format(partition_temp["free"]) or "-" - else - partition_temp["used"], partition_temp["free"], partition_temp["usage"] = 0,0,"-" - partition_temp["used_formated"] = "-" - partition_temp["free_formated"] = "-" - end - -- if disk_temp["p_table"] == "MBR" and (partition_temp["number"] < 4) and (partition_temp["number"] > 0) then - -- local real_size_sec = tonumber(nixio.fs.readfile("/sys/block/"..device.."/"..partition_temp["name"].."/size")) * tonumber(disk_temp.phy_sec) - -- if real_size_sec ~= partition_temp["size"] then - -- disk_temp["extended_partition_index"] = partition_temp["number"] - -- partition_temp["type"] = "extended" - -- partition_temp["size"] = real_size_sec - -- partition_temp["fs"] = "-" - -- partition_temp["logicals"] = {} - -- else - -- partition_temp["type"] = "primary" - -- end - -- end - - table.insert(partitions_temp, partition_temp) - end - end - if disk_temp and disk_temp["p_table"] == "MBR" then - for i, p in ipairs(partitions_temp) do - if disk_temp["extended_partition_index"] and p["number"] > 4 then - if tonumber(p["sec_end"]) <= tonumber(partitions_temp[disk_temp["extended_partition_index"]]["sec_end"]) and tonumber(p["sec_start"]) >= tonumber(partitions_temp[disk_temp["extended_partition_index"]]["sec_start"]) then - p["type"] = "logical" - table.insert(partitions_temp[disk_temp["extended_partition_index"]]["logicals"], i) - end - elseif (p["number"] < 4) and (p["number"] > 0) then - local s = nixio.fs.readfile("/sys/block/"..device.."/"..p["name"].."/size") - if s then - local real_size_sec = tonumber(s) * tonumber(disk_temp.phy_sec) - -- if size not equal, it's an extended - if real_size_sec ~= p["size"] then - disk_temp["extended_partition_index"] = i - p["type"] = "extended" - p["size"] = real_size_sec - p["fs"] = "-" - p["logicals"] = {} - else - p["type"] = "primary" - end - else - -- if not found in "/sys/block" - p["type"] = "primary" - end - end - end - end - result = disk_temp - result.partitions = partitions_temp - - return result -end - -local mddetail = function(mdpath) - local detail = {} - local path = mdpath:match("^/dev/md%d+$") - if path then - local mdadm = io.popen(d.command.mdadm .. " --detail "..path, "r") - for line in mdadm:lines() do - local key, value = line:match("^%s*(.+) : (.+)") - if key then - detail[key] = value - end - end - mdadm:close() - end - return detail -end - --- return {{device="", mount_points="", fs="", mount_options="", dump="", pass=""}..} -d.get_mount_points = function() - local mount - local res = {} - local h ={"device", "mount_point", "fs", "mount_options", "dump", "pass"} - for mount in proc_mounts:gmatch("[^\n]+") do - local device = mount:match("^([^%s]+)%s+.+") - -- only show /dev/xxx device - if device and device:match("/dev/") then - res[#res+1] = {} - local i = 0 - for v in mount:gmatch("[^%s]+") do - i = i + 1 - res[#res][h[i]] = v - end - end - end - return res -end - -d.get_disk_info = function(device, wakeup) - --[[ return: - { - path, model, sn, size, size_mounted, flags, type, temp, p_table, logic_sec, phy_sec, sec_size, sata_ver, rota_rate, status, health, - partitions = { - 1 = { number, name, sec_start, sec_end, size, size_mounted, fs, tag_name, type, flags, mount_point, usage, used, free, used_formated, free_formated}, - 2 = { number, name, sec_start, sec_end, size, size_mounted, fs, tag_name, type, flags, mount_point, usage, used, free, used_formated, free_formated}, - ... - } - --raid devices only - level, members, members_str - } - --]] - if not device then return end - local disk_info - local smart_info = get_smart_info(device) - - -- check if divice is the member of raid - smart_info["p_table"] = is_raid_member(device..'0') - -- if status is not active(standby), only check smart_info. - -- if only weakup == true, weakup the disk and check parted_info. - if smart_info.status ~= "STANDBY" or wakeup or (smart_info["p_table"] and not smart_info["p_table"]:match("Raid")) or device:match("^md") then - disk_info = get_parted_info(device) - disk_info["sec_size"] = disk_info["logic_sec"] .. "/" .. disk_info["phy_sec"] - disk_info["size_formated"] = byte_format(tonumber(disk_info["size"])) - -- if status is standby, after get part info, the disk is weakuped, then get smart_info again for more informations - if smart_info.status ~= "ACTIVE" then smart_info = get_smart_info(device) end - else - disk_info = {} - end - - for k, v in pairs(smart_info) do - disk_info[k] = v - end - - if disk_info.type and disk_info.type:match("md") then - local raid_info = d.list_raid_devices()[disk_info["path"]:match("/dev/(.+)")] - for k, v in pairs(raid_info) do - disk_info[k] = v - end - end - return disk_info -end - -d.list_raid_devices = function() - local fs = require "nixio.fs" - - local raid_devices = {} - if not fs.access("/proc/mdstat") then return raid_devices end - local mdstat = io.open("/proc/mdstat", "r") - for line in mdstat:lines() do - - -- md1 : active raid1 sdb2[1] sda2[0] - -- md127 : active raid5 sdh1[6] sdg1[4] sdf1[3] sde1[2] sdd1[1] sdc1[0] - local device_info = {} - local mdpath, list = line:match("^(md%d+) : (.+)") - if mdpath then - local members = {} - for member in string.gmatch(list, "%S+") do - member_path = member:match("^(%S+)%[%d+%]") - if member_path then - member = '/dev/'..member_path - end - table.insert(members, member) - end - local active = table.remove(members, 1) - local level = "-" - if active == "active" then - level = table.remove(members, 1) - end - - local size = tonumber(fs.readfile(string.format("/sys/class/block/%s/size", mdpath))) - local ss = tonumber(fs.readfile(string.format("/sys/class/block/%s/queue/logical_block_size", mdpath))) - - device_info["path"] = "/dev/"..mdpath - device_info["size"] = size*ss - device_info["size_formated"] = byte_format(size*ss) - device_info["active"] = active:upper() - device_info["level"] = level - device_info["members"] = members - device_info["members_str"] = table.concat(members, ", ") - - -- Get more info from output of mdadm --detail - local detail = mddetail(device_info["path"]) - device_info["status"] = detail["State"]:upper() - - raid_devices[mdpath] = device_info - end - end - mdstat:close() - - return raid_devices -end - --- Collect Devices information - --[[ return: - { - sda={ - path, model, inuse, size_formated, - partitions={ - { name, inuse, size_formated } - ... - } - } - .. - } - --]] -d.list_devices = function() - local fs = require "nixio.fs" - - -- get all device names (sdX and mmcblkX) - local target_devnames = {} - for dev in fs.dir("/dev") do - if dev:match("^sd[a-z]$") - or dev:match("^mmcblk%d+$") - or dev:match("^sata[a-z]$") - or dev:match("^nvme%d+n%d+$") - then - table.insert(target_devnames, dev) - end - end - - local devices = {} - for i, bname in pairs(target_devnames) do - local device_info = {} - local device = "/dev/" .. bname - local size = tonumber(fs.readfile(string.format("/sys/class/block/%s/size", bname)) or "0") - local ss = tonumber(fs.readfile(string.format("/sys/class/block/%s/queue/logical_block_size", bname)) or "0") - local model = fs.readfile(string.format("/sys/class/block/%s/device/model", bname)) - local partitions = {} - for part in nixio.fs.glob("/sys/block/" .. bname .."/" .. bname .. "*") do - local pname = nixio.fs.basename(part) - local psize = byte_format(tonumber(nixio.fs.readfile(part .. "/size"))*ss) - local mount_point = get_mount_point(pname) - if mount_point then device_info["inuse"] = true end - table.insert(partitions, {name = pname, size_formated = psize, inuse = mount_point}) - end - - device_info["path"] = device - device_info["size_formated"] = byte_format(size*ss) - device_info["model"] = model - device_info["partitions"] = partitions - -- true or false - device_info["inuse"] = device_info["inuse"] or get_mount_point(bname) - - local udevinfo = {} - if luci.sys.exec("which udevadm") ~= "" then - local udevadm = io.popen("udevadm info --query=property --name="..device) - for attr in udevadm:lines() do - local k, v = attr:match("(%S+)=(%S+)") - udevinfo[k] = v - end - udevadm:close() - - device_info["info"] = udevinfo - if udevinfo["ID_MODEL"] then device_info["model"] = udevinfo["ID_MODEL"] end - end - devices[bname] = device_info - end - -- luci.util.perror(luci.util.serialize_json(devices)) - return devices -end - --- get formart cmd -d.get_format_cmd = function() - local AVAILABLE_FMTS = { - ext2 = { cmd = "mkfs.ext2", option = "-F -E lazy_itable_init=1" }, - ext3 = { cmd = "mkfs.ext3", option = "-F -E lazy_itable_init=1" }, - ext4 = { cmd = "mkfs.ext4", option = "-F -E lazy_itable_init=1" }, - fat32 = { cmd = "mkfs.vfat", option = "-F" }, - exfat = { cmd = "mkexfat", option = "-f" }, - hfsplus = { cmd = "mkhfs", option = "-f" }, - ntfs = { cmd = "mkntfs", option = "-f" }, - swap = { cmd = "mkswap", option = "" }, - btrfs = { cmd = "mkfs.btrfs", option = "-f" } - } - result = {} - for fmt, obj in pairs(AVAILABLE_FMTS) do - local cmd = luci.sys.exec("/usr/bin/which " .. obj["cmd"]) - if cmd:match(obj["cmd"]) then - result[fmt] = { cmd = cmd:match("^.+"..obj["cmd"]) ,option = obj["option"] } - end - end - return result -end - -d.create_raid = function(rname, rlevel, rmembers) - local mb = {} - for _, v in ipairs(rmembers) do - mb[v]=v - end - rmembers = {} - for _, v in pairs(mb) do - table.insert(rmembers, v) - end - if type(rname) == "string" then - if rname:match("^md%d-%s+") then - rname = "/dev/"..rname:match("^(md%d-)%s+") - elseif rname:match("^/dev/md%d-%s+") then - rname = "/dev/"..rname:match("^(/dev/md%d-)%s+") - elseif not rname:match("/") then - rname = "/dev/md/".. rname - else - return "ERR: Invalid raid name" - end - else - local mdnum = 0 - for num=1,127 do - local md = io.open("/dev/md"..tostring(num), "r") - if md == nil then - mdnum = num - break - else - io.close(md) - end - end - if mdnum == 0 then return "ERR: Cannot find proper md number" end - rname = "/dev/md"..mdnum - end - - if rlevel == "5" or rlevel == "6" then - if #rmembers < 3 then return "ERR: Not enough members" end - end - if rlevel == "10" then - if #rmembers < 4 then return "ERR: Not enough members" end - end - if #rmembers < 2 then return "ERR: Not enough members" end - local cmd = d.command.mdadm .. " --create "..rname.." --run --assume-clean --homehost=any --level=" .. rlevel .. " --raid-devices=" .. #rmembers .. " " .. table.concat(rmembers, " ") - local res = luci.util.exec(cmd) - return res -end - -d.gen_mdadm_config = function() - if not nixio.fs.access("/etc/config/mdadm") then return end - local uci = require "luci.model.uci" - local x = uci.cursor() - -- delete all array sections - x:foreach("mdadm", "array", function(s) x:delete("mdadm",s[".name"]) end) - local cmd = d.command.mdadm .. " -D -s" - --ARRAY /dev/md1 metadata=1.2 name=any:1 UUID=f998ae14:37621b27:5c49e850:051f6813 - --ARRAY /dev/md3 metadata=1.2 name=any:3 UUID=c068c141:4b4232ca:f48cbf96:67d42feb - for _, v in ipairs(luci.util.execl(cmd)) do - local device, uuid = v:match("^ARRAY%s-([^%s]+)%s-[^%s]-%s-[^%s]-%s-UUID=([^%s]+)%s-") - if device and uuid then - local section_name = x:add("mdadm", "array") - x:set("mdadm", section_name, "device", device) - x:set("mdadm", section_name, "uuid", uuid) - end - end - x:commit("mdadm") - -- enable mdadm - luci.util.exec("/etc/init.d/mdadm enable") -end - --- list btrfs filesystem device --- {uuid={uuid, label, members, size, used}...} -d.list_btrfs_devices = function() - local btrfs_device = {} - if not d.command.btrfs then return btrfs_device end - local line, _uuid - for _, line in ipairs(luci.util.execl(d.command.btrfs .. " filesystem show -d --raw")) - do - local label, uuid = line:match("^Label:%s+([^%s]+)%s+uuid:%s+([^%s]+)") - if label and uuid then - _uuid = uuid - local _label = label:match("^'([^']+)'") - btrfs_device[_uuid] = {label = _label or label, uuid = uuid} - -- table.insert(btrfs_device, {label = label, uuid = uuid}) - end - local used = line:match("Total devices[%w%s]+used%s+(%d+)$") - if used then - btrfs_device[_uuid]["used"] = tonumber(used) - btrfs_device[_uuid]["used_formated"] = byte_format(tonumber(used)) - end - local size, device = line:match("devid[%w.%s]+size%s+(%d+)[%w.%s]+path%s+([^%s]+)$") - if size and device then - btrfs_device[_uuid]["size"] = btrfs_device[_uuid]["size"] and btrfs_device[_uuid]["size"] + tonumber(size) or tonumber(size) - btrfs_device[_uuid]["size_formated"] = byte_format(btrfs_device[_uuid]["size"]) - btrfs_device[_uuid]["members"] = btrfs_device[_uuid]["members"] and btrfs_device[_uuid]["members"]..", "..device or device - end - end - return btrfs_device -end - -d.create_btrfs = function(blabel, blevel, bmembers) - -- mkfs.btrfs -L label -d blevel /dev/sda /dev/sdb - if not d.command.btrfs or type(bmembers) ~= "table" or next(bmembers) == nil then return "ERR no btrfs support or no members" end - local label = blabel and " -L " .. blabel or "" - local cmd = "mkfs.btrfs -f " .. label .. " -d " .. blevel .. " " .. table.concat(bmembers, " ") - return luci.util.exec(cmd) -end - --- get btrfs info --- {uuid, label, members, data_raid_level,metadata_raid_lavel, size, used, size_formated, used_formated, free, free_formated, usage} -d.get_btrfs_info = function(m_point) - local btrfs_info = {} - if not m_point or not d.command.btrfs then return btrfs_info end - local cmd = d.command.btrfs .. " filesystem show --raw " .. m_point - local _, line, uuid, _label, members - for _, line in ipairs(luci.util.execl(cmd)) do - if not uuid and not _label then - _label, uuid = line:match("^Label:%s+([^%s]+)%s+uuid:%s+([^s]+)") - else - local mb = line:match("%s+devid.+path%s+([^%s]+)") - if mb then - members = members and (members .. ", ".. mb) or mb - end - end - end - - if not _label or not uuid then return btrfs_info end - local label = _label:match("^'([^']+)'") - cmd = d.command.btrfs .. " filesystem usage -b " .. m_point - local used, free, data_raid_level, metadata_raid_lavel - for _, line in ipairs(luci.util.execl(cmd)) do - if not used then - used = line:match("^%s+Used:%s+(%d+)") - elseif not free then - free = line:match("^%s+Free %(estimated%):%s+(%d+)") - elseif not data_raid_level then - data_raid_level = line:match("^Data,%s-(%w+)") - elseif not metadata_raid_lavel then - metadata_raid_lavel = line:match("^Metadata,%s-(%w+)") - end - end - if used and free and data_raid_level and metadata_raid_lavel then - used = tonumber(used) - free = tonumber(free) - btrfs_info = { - uuid = uuid, - label = label, - data_raid_level = data_raid_level, - metadata_raid_lavel = metadata_raid_lavel, - used = used, - free = free, - size = used + free, - size_formated = byte_format(used + free), - used_formated = byte_format(used), - free_formated = byte_format(free), - members = members, - usage = string.format("%.2f",(used / (free+used) * 100)) .. "%" - } - end - return btrfs_info -end - --- get btrfs subvolume --- {id={id, gen, top_level, path, snapshots, otime, default_subvolume}...} -d.get_btrfs_subv = function(m_point, snapshot) -local subvolume = {} -if not m_point or not d.command.btrfs then return subvolume end - --- get default subvolume -local cmd = d.command.btrfs .. " subvolume get-default " .. m_point -local res = luci.util.exec(cmd) -local default_subvolume_id = res:match("^ID%s+([^%s]+)") - --- get the root subvolume -if not snapshot then - local _, line, section_snap, _uuid, _otime, _id, _snap - cmd = d.command.btrfs .. " subvolume show ".. m_point - for _, line in ipairs(luci.util.execl(cmd)) do - if not section_snap then - if not _uuid then - _uuid = line:match("^%s-UUID:%s+([^%s]+)") - elseif not _otime then - _otime = line:match("^%s+Creation time:%s+(.+)") - elseif not _id then - _id = line:match("^%s+Subvolume ID:%s+([^%s]+)") - elseif line:match("^%s+(Snapshot%(s%):)") then - section_snap = true - end - else - local snapshot = line:match("^%s+(.+)") - if snapshot then - _snap = _snap and (_snap ..", /".. snapshot) or ("/"..snapshot) - end - end - end - if _uuid and _otime and _id then - subvolume["0".._id] = {id = _id , uuid = _uuid, otime = _otime, snapshots = _snap, path = "/"} - if default_subvolume_id == _id then - subvolume["0".._id].default_subvolume = 1 - end - end -end - --- get subvolume of btrfs -cmd = d.command.btrfs .. " subvolume list -gcu" .. (snapshot and "s " or " ") .. m_point -for _, line in ipairs(luci.util.execl(cmd)) do - -- ID 259 gen 11 top level 258 uuid 26ae0c59-199a-cc4d-bd58-644eb4f65d33 path 1a/2b' - local id, gen, top_level, uuid, path, otime, otime2 - if snapshot then - id, gen, top_level, otime, otime2, uuid, path = line:match("^ID%s+([^%s]+)%s+gen%s+([^%s]+)%s+cgen.-top level%s+([^%s]+)%s+otime%s+([^%s]+)%s+([^%s]+)%s+uuid%s+([^%s]+)%s+path%s+([^%s]+)%s-$") - else - id, gen, top_level, uuid, path = line:match("^ID%s+([^%s]+)%s+gen%s+([^%s]+)%s+cgen.-top level%s+([^%s]+)%s+uuid%s+([^%s]+)%s+path%s+([^%s]+)%s-$") - end - if id and gen and top_level and uuid and path then - subvolume[id] = {id = id, gen = gen, top_level = top_level, otime = (otime and otime or "") .." ".. (otime2 and otime2 or ""), uuid = uuid, path = '/'.. path} - if not snapshot then - -- use btrfs subv show to get snapshots - local show_cmd = d.command.btrfs .. " subvolume show "..m_point.."/"..path - local __, line_show, section_snap - for __, line_show in ipairs(luci.util.execl(show_cmd)) do - if not section_snap then - local create_time = line_show:match("^%s+Creation time:%s+(.+)") - if create_time then - subvolume[id]["otime"] = create_time - elseif line_show:match("^%s+(Snapshot%(s%):)") then - section_snap = "true" - end - else - local snapshot = line_show:match("^%s+(.+)") - subvolume[id]["snapshots"] = subvolume[id]["snapshots"] and (subvolume[id]["snapshots"] .. ", /".. snapshot) or ("/"..snapshot) - end - end - end - end -end -if subvolume[default_subvolume_id] then - subvolume[default_subvolume_id].default_subvolume = 1 -end --- if m_point == "/tmp/.btrfs_tmp" then --- luci.util.exec("umount " .. m_point) --- end -return subvolume -end - -d.format_partition = function(partition, fs) - local partition_name = "/dev/".. partition - if not nixio.fs.access(partition_name) then - return 500, "Partition NOT found!" - end - - local format_cmd = d.get_format_cmd() - if not format_cmd[fs] then - return 500, "Filesystem NOT support!" - end - local cmd = format_cmd[fs].cmd .. " " .. format_cmd[fs].option .. " " .. partition_name - local res = luci.util.exec(cmd .. " 2>&1") - if res and res:lower():match("error+") then - return 500, res - else - return 200, "OK" - end -end - -return d diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm b/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm deleted file mode 100755 index 1ad4eca3b..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/disabled_button.htm +++ /dev/null @@ -1,7 +0,0 @@ -<%+cbi/valueheader%> - <% if self:cfgvalue(section) ~= false then %> - " type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> <% if self.view_disabled then %> disabled <% end %>/> - <% else %> - - - <% end %> -<%+cbi/valuefooter%> \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm b/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm deleted file mode 100755 index 18e306e27..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/format_button.htm +++ /dev/null @@ -1,7 +0,0 @@ -<%+cbi/valueheader%> - <% if self:cfgvalue(section) ~= false then %> - " onclick="event.preventDefault();partition_format('<%=self.partitions[section].name%>', '<%=self.format_cmd%>', '<%=self.inputtitle%>');" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> <% if self.view_disabled then %> disabled <% end %>/> - <% else %> - - - <% end %> -<%+cbi/valuefooter%> diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm b/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm deleted file mode 100755 index b1b193257..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/inlinebutton.htm +++ /dev/null @@ -1,7 +0,0 @@ -
- <% if self:cfgvalue(section) ~= false then %> - " type="submit"" <% if self.disable then %>disabled <% end %><%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> - <% else %> - - - <% end %> -
diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm b/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm deleted file mode 100755 index 69aa65e00..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/xnullsection.htm +++ /dev/null @@ -1,37 +0,0 @@ -
- <% if self.title and #self.title > 0 then -%> - <%=self.title%> - <%- end %> - <% if self.description and #self.description > 0 then -%> -
<%=self.description%>
- <%- end %> -
-
- <% self:render_children(1, scope or {}) %> -
- <% if self.error and self.error[1] then -%> -
-
    <% for _, e in ipairs(self.error[1]) do -%> -
  • - <%- if e == "invalid" then -%> - <%:One or more fields contain invalid values!%> - <%- elseif e == "missing" then -%> - <%:One or more required fields have no value!%> - <%- else -%> - <%=pcdata(e)%> - <%- end -%> -
  • - <%- end %>
-
- <%- end %> -
-
-<%- - if type(self.hidden) == "table" then - for k, v in pairs(self.hidden) do --%> - -<%- - end - end -%> \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm b/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm deleted file mode 100755 index a831bfc77..000000000 --- a/luci-app-diskman/luasrc/view/diskman/cbi/xsimpleform.htm +++ /dev/null @@ -1,88 +0,0 @@ -<% if not self.embedded then %> -
> - - - <% - end - - %>
<% - - if self.title and #self.title > 0 then - %>

<%=self.title%>

<% - end - - if self.description and #self.description > 0 then - %>
<%=self.description%>
<% - end - - self:render_children() - - %>
<% - - if self.message then - %>
<%=self.message%>
<% - end - - if self.errmessage then - %>
<%=self.errmessage%>
<% - end - - if not self.embedded then - if type(self.hidden) == "table" then - local k, v - for k, v in pairs(self.hidden) do - %><% - end - end - - local display_back = (self.redirect) - local display_cancel = (self.cancel ~= false and self.on_cancel) - local display_skip = (self.flow and self.flow.skip) - local display_submit = (self.submit ~= false) - local display_reset = (self.reset ~= false) - - if display_back or display_cancel or display_skip or display_submit or display_reset then - %>
<% - - if display_back then - %> <% - end - - if display_cancel then - local label = pcdata(self.cancel or translate("Cancel")) - %> <% - end - - if display_skip then - %> <% - end - - if display_submit then - local label = pcdata(self.submit or translate("Submit")) - %> <% - end - - if display_reset then - local label = pcdata(self.reset or translate("Reset")) - %> <% - end - - %>
<% - end - - %>
<% - end -%> - - diff --git a/luci-app-diskman/luasrc/view/diskman/disk_info.htm b/luci-app-diskman/luasrc/view/diskman/disk_info.htm deleted file mode 100755 index 118acd50d..000000000 --- a/luci-app-diskman/luasrc/view/diskman/disk_info.htm +++ /dev/null @@ -1,108 +0,0 @@ - diff --git a/luci-app-diskman/luasrc/view/diskman/partition_info.htm b/luci-app-diskman/luasrc/view/diskman/partition_info.htm deleted file mode 100755 index 78f5c1bd7..000000000 --- a/luci-app-diskman/luasrc/view/diskman/partition_info.htm +++ /dev/null @@ -1,129 +0,0 @@ - - \ No newline at end of file diff --git a/luci-app-diskman/luasrc/view/diskman/smart_detail.htm b/luci-app-diskman/luasrc/view/diskman/smart_detail.htm deleted file mode 100755 index 56a9139f0..000000000 --- a/luci-app-diskman/luasrc/view/diskman/smart_detail.htm +++ /dev/null @@ -1,79 +0,0 @@ - - - S.M.A.R.T detail of <%=dev%> - - - - -
-
- <%:S.M.A.R.T Attrbutes%>: /dev/<%=dev%> - - - <% if dev:match("nvme") then %> - - <% else %> - - - - - - - - - - <% end %> - - - - -
<%:ID%><%:Attrbute%><%:Flag%><%:Value%><%:Worst%><%:Thresh%><%:Type%><%:Updated%><%:Raw%>

<%:Collecting data...%>
-
-
- - \ No newline at end of file diff --git a/luci-app-diskman/po/zh-cn/diskman.po b/luci-app-diskman/po/zh-cn/diskman.po deleted file mode 100755 index f380fc586..000000000 --- a/luci-app-diskman/po/zh-cn/diskman.po +++ /dev/null @@ -1,239 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8\n" - -msgid "DiskMan" -msgstr "DiskMan 磁盘管理" - -msgid "Manage Disks over LuCI." -msgstr "通过 LuCI 管理磁盘" - -msgid "Rescan Disks" -msgstr "重新扫描磁盘" - -msgid "Disks" -msgstr "磁盘" - -msgid "Path" -msgstr "路径" - -msgid "Serial Number" -msgstr "序列号" - -msgid "Temp" -msgstr "温度" - -msgid "Partition Table" -msgstr "分区表" - -msgid "SATA Version" -msgstr "SATA 版本" - -msgid "Health" -msgstr "健康" - -msgid "File System" -msgstr "文件系统" - -msgid "Mount Options" -msgstr "挂载选项" - -msgid "Mount" -msgstr "挂载" - -msgid "Umount" -msgstr "卸载" - -msgid "Eject" -msgstr "弹出" - -msgid "New" -msgstr "创建" - -msgid "Remove" -msgstr "移除" - -msgid "Format" -msgstr "格式化" - -msgid "Start Sector" -msgstr "起始扇区" - -msgid "End Sector" -msgstr "中止扇区" - -msgid "Usage" -msgstr "用量" - -msgid "Used" -msgstr "已使用" - -msgid "Free Space" -msgstr "空闲空间" - -msgid "Model" -msgstr "型号" - -msgid "Size" -msgstr "容量" - -msgid "Status" -msgstr "状态" - -msgid "Mount Point" -msgstr "挂载点" - -msgid "Sector Size" -msgstr "扇区/物理扇区大小" - -msgid "Rotation Rate" -msgstr "转速" - -msgid "RAID Devices" -msgstr "RAID 设备" - -msgid "RAID mode" -msgstr "RAID 模式" - -msgid "Members" -msgstr "成员" - -msgid "Active" -msgstr "活动" - -msgid "RAID Creation" -msgstr "RAID 创建" - -msgid "Raid Name" -msgstr "RAID 名称" - -msgid "Raid Level" -msgstr "RAID 级别" - -msgid "Raid Member" -msgstr "磁盘阵列成员" - -msgid "Create Raid" -msgstr "创建 RAID" - -msgid "Partition Management" -msgstr "分区管理" - -msgid "Partition Disk over LuCI." -msgstr "通过LuCI分区磁盘。" - -msgid "Device Info" -msgstr "设备信息" - -msgid "Disk Man" -msgstr "磁盘管理" - -msgid "Partitions Info" -msgstr "分区信息" - -msgid "Default 2048 sector alignment, support +size{b,k,m,g,t} in End Sector" -msgstr "默认2048扇区对齐,【中止扇区】支持 +容量{b,k,m,g,t} 格式,例:+500m +10g +1t" - -msgid "Multiple Devices Btrfs Creation" -msgstr "Btrfs 阵列创建" - -msgid "Label" -msgstr "卷标" - -msgid "Btrfs Label" -msgstr "Btrfs 卷标" - -msgid "Btrfs Raid Level" -msgstr "Btrfs Raid 级别" - -msgid "Btrfs Member" -msgstr "Btrfs 整列成员" - -msgid "Create Btrfs" -msgstr "创建 Btrfs" - -msgid "New Snapshot" -msgstr "新建快照" - -msgid "SubVolumes" -msgstr "子卷" - -msgid "Top Level" -msgstr "父ID" - -msgid "Manage Btrfs" -msgstr "Btrfs 管理" - -msgid "Otime" -msgstr "创建时间" - -msgid "Snapshots" -msgstr "快照" - -msgid "Set Default" -msgstr "默认子卷" - -msgid "Source Path" -msgstr "源目录" - -msgid "Readonly" -msgstr "只读" - -msgid "Delete" -msgstr "删除" - -msgid "Create" -msgstr "创建" - -msgid "Destination Path (optional)" -msgstr "目标目录(可选)" - -msgid "Metadata" -msgstr "元数据" - -msgid "Data" -msgstr "数据" - -msgid "Btrfs Info" -msgstr "Btrfs 信息" - -msgid "The source path for create the snapshot" -msgstr "创建快照的源数据目录" - -msgid "The path where you want to store the snapshot" -msgstr "存放快照数据目录" - -msgid "Please input Source Path of snapshot, Source Path must start with '/'" -msgstr "请输入快照源路径,源路径必须以'/'开头" - -msgid "Please input Subvolume Path, Subvolume must start with '/'" -msgstr "请输入子卷路径,子卷路径必须以'/'开头" - -msgid "is in use! please unmount it first!" -msgstr "正在被使用!请先卸载!" - -msgid "Partition NOT found!" -msgstr "分区未找到!" - -msgid "Filesystem NOT support!" -msgstr "文件系统不支持!" - -msgid "Invalid Start Sector!" -msgstr "无效的起始扇区!" - -msgid "Invalid End Sector" -msgstr "无效的终止扇区!" - -msgid "Partition not exists!" -msgstr "分区不存在!" - -msgid "Creation" -msgstr "创建" - -msgid "Please select file system!" -msgstr "请选择文件系统!" - -msgid "Format partation:" -msgstr "格式化分区:" - -msgid "Warnning !! \nTHIS WILL OVERWRITE EXISTING PARTITIONS!! \nModify the partition table?" -msgstr "警告!!\n此操作会覆盖现有分区\n确定修改分区表?" diff --git a/luci-app-diskman/po/zh_Hans b/luci-app-diskman/po/zh_Hans deleted file mode 100755 index 41451e4a1..000000000 --- a/luci-app-diskman/po/zh_Hans +++ /dev/null @@ -1 +0,0 @@ -zh-cn \ No newline at end of file diff --git a/luci-app-dockerman/Makefile b/luci-app-dockerman/Makefile deleted file mode 100755 index 51dfa5c09..000000000 --- a/luci-app-dockerman/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=LuCI Support for docker -LUCI_DEPENDS:=@(aarch64||arm||x86_64) \ - +luci-compat \ - +luci-lib-docker \ - +luci-lib-ip \ - +docker \ - +dockerd \ - +ttyd -LUCI_PKGARCH:=all - -PKG_LICENSE:=AGPL-3.0 -PKG_MAINTAINER:=lisaac \ - Florian Eckert - -PKG_VERSION:=v0.5.25 - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-dockerman/depends.lst b/luci-app-dockerman/depends.lst deleted file mode 100755 index 8a62f6a74..000000000 --- a/luci-app-dockerman/depends.lst +++ /dev/null @@ -1 +0,0 @@ -ttyd docker-cli \ No newline at end of file diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg deleted file mode 100755 index 4165f90bd..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/containers.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Docker icon - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png deleted file mode 100755 index f156dc1c7..000000000 Binary files a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-icon.png and /dev/null differ diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css deleted file mode 100755 index 911693b62..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/file-manager.css +++ /dev/null @@ -1,91 +0,0 @@ -.fb-container { - margin-top: 1rem; -} -.fb-container .cbi-button { - height: 1.8rem; -} -.fb-container .cbi-input-text { - margin-bottom: 1rem; - width: 100%; -} -.fb-container .panel-title { - padding-bottom: 0; - width: 50%; - border-bottom: none; -} -.fb-container .panel-container { - display: flex; - align-items: center; - justify-content: space-between; - padding-bottom: 1rem; - border-bottom: 1px solid #eee; -} -.fb-container .upload-container { - display: none; - margin: 1rem 0; -} -.fb-container .upload-file { - margin-right: 2rem; -} -.fb-container .cbi-value-field { - text-align: left; -} -.fb-container .parent-icon strong { - margin-left: 1rem; -} -.fb-container td[class$="-icon"] { - cursor: pointer; -} -.fb-container .file-icon, .fb-container .folder-icon, .fb-container .link-icon { - position: relative; -} -.fb-container .file-icon:before, .fb-container .folder-icon:before, .fb-container .link-icon:before { - display: inline-block; - width: 1.5rem; - height: 1.5rem; - content: ''; - background-size: contain; - margin: 0 0.5rem 0 1rem; - vertical-align: middle; -} -.fb-container .file-icon:before { - background-image: url(file-icon.png); -} -.fb-container .folder-icon:before { - background-image: url(folder-icon.png); -} -.fb-container .link-icon:before { - background-image: url(link-icon.png); -} -@media screen and (max-width: 480px) { - .fb-container .upload-file { - width: 14.6rem; - } - .fb-container .cbi-value-owner, - .fb-container .cbi-value-perm { - display: none; - } -} - -.cbi-section-table { - width: 100%; -} - -.cbi-section-table-cell { - text-align: right; -} - -.cbi-button-install { -border-color: #c44; - color: #c44; - margin-left: 3px; -} - -.cbi-value-field { - padding: 10px 0; -} - -.parent-icon { - height: 1.8rem; - padding: 10px 0; -} \ No newline at end of file diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png deleted file mode 100755 index 1370df3ad..000000000 Binary files a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/folder-icon.png and /dev/null differ diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg deleted file mode 100755 index 90ca5a1c7..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/images.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png deleted file mode 100755 index 03cc82cdf..000000000 Binary files a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/link-icon.png and /dev/null differ diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/networks.svg b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/networks.svg deleted file mode 100755 index 3eb12a393..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/networks.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js b/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js deleted file mode 100755 index d9c06667f..000000000 --- a/luci-app-dockerman/htdocs/luci-static/resources/dockerman/tar.min.js +++ /dev/null @@ -1,185 +0,0 @@ -// https://github.com/thiscouldbebetter/TarFileExplorer -class TarFileTypeFlag -{constructor(value,name) -{this.value=value;this.id="_"+this.value;this.name=name;} -static _instances;static Instances() -{if(TarFileTypeFlag._instances==null) -{TarFileTypeFlag._instances=new TarFileTypeFlag_Instances();} -return TarFileTypeFlag._instances;}} -class TarFileTypeFlag_Instances -{constructor() -{this.Normal=new TarFileTypeFlag("0","Normal");this.HardLink=new TarFileTypeFlag("1","Hard Link");this.SymbolicLink=new TarFileTypeFlag("2","Symbolic Link");this.CharacterSpecial=new TarFileTypeFlag("3","Character Special");this.BlockSpecial=new TarFileTypeFlag("4","Block Special");this.Directory=new TarFileTypeFlag("5","Directory");this.FIFO=new TarFileTypeFlag("6","FIFO");this.ContiguousFile=new TarFileTypeFlag("7","Contiguous File");this.LongFilePath=new TarFileTypeFlag("L","././@LongLink");this._All=[this.Normal,this.HardLink,this.SymbolicLink,this.CharacterSpecial,this.BlockSpecial,this.Directory,this.FIFO,this.ContiguousFile,this.LongFilePath,];for(var i=0;ia+=String.fromCharCode(b),"");entryNext.header.fileName=entryNext.header.fileName.replace(/\0/g,"");entries.splice(i,1);i--;}}} -downloadAs(fileNameToSaveAs) -{return FileHelper.saveBytesAsFile -(this.toBytes(),fileNameToSaveAs)} -entriesForDirectories() -{return this.entries.filter(x=>x.header.typeFlag.name==TarFileTypeFlag.Instances().Directory);} -toBytes() -{this.toBytes_PrependLongPathEntriesAsNeeded();var fileAsBytes=[];var entriesAsByteArrays=this.entries.map(x=>x.toBytes());this.consolidateLongPathEntries();for(var i=0;imaxLength) -{var entryFileNameAsBytes=entryFileName.split("").map(x=>x.charCodeAt(0));var entryContainingLongPathToPrepend=TarFileEntry.fileNew -(typeFlagLongPath.name,entryFileNameAsBytes);entryContainingLongPathToPrepend.header.typeFlag=typeFlagLongPath;entryContainingLongPathToPrepend.header.timeModifiedInUnixFormat=entryHeader.timeModifiedInUnixFormat;entryContainingLongPathToPrepend.header.checksumCalculate();entryHeader.fileName=entryFileName.substr(0,maxLength)+String.fromCharCode(0);entries.splice(i,0,entryContainingLongPathToPrepend);i++;}}} -toString() -{var newline="\n";var returnValue="[TarFile]"+newline;for(var i=0;i{var fileLoadedAsBinaryString=fileLoadedEvent.target.result;var fileLoadedAsBytes=ByteHelper.stringUTF8ToBytes(fileLoadedAsBinaryString);callback(fileToLoad.name,fileLoadedAsBytes);} -fileReader.readAsBinaryString(fileToLoad);} -static loadFileAsText(fileToLoad,callback) -{var fileReader=new FileReader();fileReader.onload=(fileLoadedEvent)=>{var textFromFileLoaded=fileLoadedEvent.target.result;callback(fileToLoad.name,textFromFileLoaded);};fileReader.readAsText(fileToLoad);} -static saveBytesAsFile(bytesToWrite,fileNameToSaveAs) -{var bytesToWriteAsArrayBuffer=new ArrayBuffer(bytesToWrite.length);var bytesToWriteAsUIntArray=new Uint8Array(bytesToWriteAsArrayBuffer);for(var i=0;i - - - - - diff --git a/luci-app-dockerman/luasrc/controller/dockerman.lua b/luci-app-dockerman/luasrc/controller/dockerman.lua deleted file mode 100755 index 7aeed56e1..000000000 --- a/luci-app-dockerman/luasrc/controller/dockerman.lua +++ /dev/null @@ -1,614 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" --- local uci = (require "luci.model.uci").cursor() - -module("luci.controller.dockerman",package.seeall) - -function index() - entry({"admin", "docker"}, - alias("admin", "docker", "config"), - _("Docker"), - 40).acl_depends = { "luci-app-dockerman" } - - entry({"admin", "docker", "config"},cbi("dockerman/configuration"),_("Configuration"), 8).leaf=true - - -- local uci = (require "luci.model.uci").cursor() - -- if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - -- local host = uci:get("dockerd", "dockerman", "remote_host") - -- local port = uci:get("dockerd", "dockerman", "remote_port") - -- if not host or not port then - -- return - -- end - -- else - -- local socket = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - -- if socket and not nixio.fs.access(socket) then - -- return - -- end - -- end - - -- if (require "luci.model.docker").new():_ping().code ~= 200 then - -- return - -- end - - entry({"admin", "docker", "overview"}, form("dockerman/overview"),_("Overview"), 2).leaf=true - entry({"admin", "docker", "containers"}, form("dockerman/containers"), _("Containers"), 3).leaf=true - entry({"admin", "docker", "images"}, form("dockerman/images"), _("Images"), 4).leaf=true - entry({"admin", "docker", "networks"}, form("dockerman/networks"), _("Networks"), 5).leaf=true - entry({"admin", "docker", "volumes"}, form("dockerman/volumes"), _("Volumes"), 6).leaf=true - entry({"admin", "docker", "events"}, call("action_events"), _("Events"), 7) - - entry({"admin", "docker", "newcontainer"}, form("dockerman/newcontainer")).leaf=true - entry({"admin", "docker", "newnetwork"}, form("dockerman/newnetwork")).leaf=true - entry({"admin", "docker", "container"}, form("dockerman/container")).leaf=true - - entry({"admin", "docker", "container_stats"}, call("action_get_container_stats")).leaf=true - entry({"admin", "docker", "containers_stats"}, call("action_get_containers_stats")).leaf=true - entry({"admin", "docker", "get_system_df"}, call("action_get_system_df")).leaf=true - entry({"admin", "docker", "container_get_archive"}, call("download_archive")).leaf=true - entry({"admin", "docker", "container_put_archive"}, call("upload_archive")).leaf=true - entry({"admin", "docker", "container_list_file"}, call("list_file")).leaf=true - entry({"admin", "docker", "container_remove_file"}, call("remove_file")).leaf=true - entry({"admin", "docker", "container_rename_file"}, call("rename_file")).leaf=true - entry({"admin", "docker", "container_export"}, call("export_container")).leaf=true - entry({"admin", "docker", "images_save"}, call("save_images")).leaf=true - entry({"admin", "docker", "images_load"}, call("load_images")).leaf=true - entry({"admin", "docker", "images_import"}, call("import_images")).leaf=true - entry({"admin", "docker", "images_get_tags"}, call("get_image_tags")).leaf=true - entry({"admin", "docker", "images_tag"}, call("tag_image")).leaf=true - entry({"admin", "docker", "images_untag"}, call("untag_image")).leaf=true - entry({"admin", "docker", "confirm"}, call("action_confirm")).leaf=true -end - -function action_get_system_df() - local res = docker.new():df() - luci.http.status(res.code, res.message) - luci.http.prepare_content("application/json") - luci.http.write_json(res.body) -end - -function scandir(id, directory) - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local i, t, popen = 0, {}, io.popen - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - local pfile = popen(cmd_docker .. ' -H "'.. hosts ..'" exec ' ..id .." ls -lh \""..directory.."\" | egrep -v '^total'") - for fileinfo in pfile:lines() do - i = i + 1 - t[i] = fileinfo - end - pfile:close() - return t -end - -function list_response(id, path, success) - luci.http.prepare_content("application/json") - local result - if success then - local rv = scandir(id, path) - result = { - ec = 0, - data = rv - } - else - result = { - ec = 1 - } - end - luci.http.write_json(result) -end - -function list_file(id) - local path = luci.http.formvalue("path") - list_response(id, path, true) -end - -function rename_file(id) - local filepath = luci.http.formvalue("filepath") - local newpath = luci.http.formvalue("newpath") - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - local success = os.execute(cmd_docker .. ' -H "'.. hosts ..'" exec '.. id ..' mv "'..filepath..'" "'..newpath..'"') - list_response(nixio.fs.dirname(filepath), success) -end - -function remove_file(id) - local path = luci.http.formvalue("path") - local isdir = luci.http.formvalue("isdir") - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - if not cmd_docker or cmd_docker:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") - local socket_path = not remote and uci:get("dockerd", "dockerman", "socket_path") or nil - local host = remote and uci:get("dockerd", "dockerman", "remote_host") or nil - local port = remote and uci:get("dockerd", "dockerman", "remote_port") or nil - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket_path then - hosts = "unix://" .. socket_path - else - return - end - path = path:gsub("<>", "/") - path = path:gsub(" ", "\ ") - local success - if isdir then - success = os.execute(cmd_docker .. ' -H "'.. hosts ..'" exec '.. id ..' rm -r "'..path..'"') - else - success = os.remove(path) - end - list_response(nixio.fs.dirname(path), success) -end - -function action_events() - local logs = "" - local query ={} - - local dk = docker.new() - query["until"] = os.time() - local events = dk:events({query = query}) - - if events.code == 200 then - for _, v in ipairs(events.body) do - local date = "unknown" - if v and v.time then - date = os.date("%Y-%m-%d %H:%M:%S", v.time) - end - - local name = v.Actor.Attributes.name or "unknown" - local action = v.Action or "unknown" - - if v and v.Type == "container" then - local id = v.Actor.ID or "unknown" - logs = logs .. string.format("[%s] %s %s Container ID: %s Container Name: %s\n", date, v.Type, action, id, name) - elseif v.Type == "network" then - local container = v.Actor.Attributes.container or "unknown" - local network = v.Actor.Attributes.type or "unknown" - logs = logs .. string.format("[%s] %s %s Container ID: %s Network Name: %s Network type: %s\n", date, v.Type, action, container, name, network) - elseif v.Type == "image" then - local id = v.Actor.ID or "unknown" - logs = logs .. string.format("[%s] %s %s Image: %s Image name: %s\n", date, v.Type, action, id, name) - end - end - end - - luci.template.render("dockerman/logs", {self={syslog = logs, title="Events"}}) -end - -local calculate_cpu_percent = function(d) - if type(d) ~= "table" then - return - end - - 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"]) - if system_delta > 0.0 then - cpu_percent = string.format("%.2f", cpu_delta / system_delta * 100.0 * cpu_count) - end - - return cpu_percent -end - -local get_memory = function(d) - if type(d) ~= "table" then - return - end - - -- 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" - - local limit =tonumber(d["memory_stats"]["limit"]) - local usage = tonumber(d["memory_stats"]["usage"]) - -- - tonumber(d["memory_stats"]["stats"]["total_cache"]) - - return usage, limit -end - -local get_rx_tx = function(d) - if type(d) ~="table" then - return - end - - local data = {} - if type(d["networks"]) == "table" then - for e, v in pairs(d["networks"]) do - data[e] = { - bw_tx = tonumber(v.tx_bytes), - bw_rx = tonumber(v.rx_bytes) - } - end - end - - return data -end - -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, ["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) - return response.code, response.body.message, { - cpu_percent = cpu_percent, - memory = { - mem_useage = mem_useage, - mem_limit = mem_limit - }, - bw_rxtx = bw_rxtx - } - else - return response.code, response.body.message - end - else - if response.code == 200 then - return 500, "container "..container_id.." not running" - else - return response.code, response.body.message - end - end - else - 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() - if data then - data = data:gsub("\n","
"):gsub(" "," ") - code = 202 - msg = data - else - code = 200 - msg = "finish" - data = "finish" - end - - luci.http.status(code, msg) - luci.http.prepare_content("application/json") - luci.http.write_json({info = data}) -end - -function export_container(id) - local dk = docker.new() - local first - - local cb = function(res, chunk) - if res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. id ..'.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - local res = dk.containers:export({id = id}, cb) -end - -function download_archive() - local id = luci.http.formvalue("id") - local path = luci.http.formvalue("path") - local filename = luci.http.formvalue("filename") or "archive" - local dk = docker.new() - local first - - local cb = function(res, chunk) - if res and res.code and res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. filename .. '.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - local res = dk.containers:get_archive({ - id = id, - query = { - path = luci.http.urlencode(path) - } - }, cb) -end - -function upload_archive(container_id) - local path = luci.http.formvalue("upload-path") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - local res = dk.containers:put_archive({ - id = container_id, - query = { - path = luci.http.urlencode(path) - }, - body = rec_send - }) - - local msg = res and res.message or res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - --- function save_images() --- local names = luci.http.formvalue("names") --- local dk = docker.new() --- local first - --- local cb = function(res, chunk) --- if res.code == 200 then --- if not first then --- first = true --- luci.http.status(res.code, res.message) --- luci.http.header('Content-Disposition', 'inline; filename="'.. "images" ..'.tar"') --- luci.http.header('Content-Type', 'application\/x-tar') --- end --- luci.ltn12.pump.all(chunk, luci.http.write) --- else --- if not first then --- first = true --- luci.http.prepare_content("text/plain") --- end --- luci.ltn12.pump.all(chunk, luci.http.write) --- end --- end - --- docker:write_status("Images: saving" .. " " .. names .. "...") --- local res = dk.images:get({ --- query = { --- names = luci.http.urlencode(names) --- } --- }, cb) --- docker:clear_status() - --- local msg = res and res.body and res.body.message or nil --- luci.http.status(res.code, msg) --- luci.http.prepare_content("application/json") --- luci.http.write_json({message = msg}) --- end - -function load_images() - local archive = luci.http.formvalue("upload-archive") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - docker:write_status("Images: loading...") - local res = dk.images:load({body = rec_send}) - local msg = res and res.body and ( res.body.message or res.body.stream or res.body.error ) or nil - if res and res.code == 200 and msg and msg:match("Loaded image ID") then - docker:clear_status() - else - docker:append_status("code:" .. (res and res.code or "500") .." ".. (msg or "unknow")) - end - - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - -function import_images() - local src = luci.http.formvalue("src") - local itag = luci.http.formvalue("tag") - local dk = docker.new() - local ltn12 = require "luci.ltn12" - - local rec_send = function(sinkout) - luci.http.setfilehandler(function (meta, chunk, eof) - if chunk then - ltn12.pump.step(ltn12.source.string(chunk), sinkout) - end - end) - end - - docker:write_status("Images: importing".. " ".. itag .."...\n") - local repo = itag and itag:match("^([^:]+)") - local tag = itag and itag:match("^[^:]-:([^:]+)") - local res = dk.images:create({ - query = { - fromSrc = luci.http.urlencode(src or "-"), - repo = repo or nil, - tag = tag or nil - }, - body = not src and rec_send or nil - }, docker.import_image_show_status_cb) - - local msg = res and res.body and ( res.body.message )or nil - if not msg and #res.body == 0 then - msg = res.body.status or res.body.error - elseif not msg and #res.body >= 1 then - msg = res.body[#res.body].status or res.body[#res.body].error - end - - if res.code == 200 and msg and msg:match("sha256:") then - docker:clear_status() - else - docker:append_status("code:" .. (res and res.code or "500") .." ".. (msg or "unknow")) - end - - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) -end - -function get_image_tags(image_id) - if not image_id then - luci.http.status(400, "no image id") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no image id"}) - return - end - - local dk = docker.new() - local res = dk.images:inspect({ - id = image_id - }) - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - - if res.code == 200 then - local tags = res.body.RepoTags - luci.http.write_json({tags = tags}) - else - local msg = res and res.body and res.body.message or nil - luci.http.write_json({message = msg or "unknow"}) - end -end - -function tag_image(image_id) - local src = luci.http.formvalue("tag") - local image_id = image_id or luci.http.formvalue("id") - - if type(src) ~= "string" or not image_id then - luci.http.status(400, "no image id or tag") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no image id or tag"}) - return - end - - local repo = src:match("^([^:]+)") - local tag = src:match("^[^:]-:([^:]+)") - local dk = docker.new() - local res = dk.images:tag({ - id = image_id, - query={ - repo=repo, - tag=tag - } - }) - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - - if res.code == 201 then - local tags = res.body.RepoTags - luci.http.write_json({tags = tags}) - else - local msg = res and res.body and res.body.message or nil - luci.http.write_json({message = msg or "unknow"}) - end -end - -function untag_image(tag) - local tag = tag or luci.http.formvalue("tag") - - if not tag then - luci.http.status(400, "no tag name") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "no tag name"}) - return - end - - local dk = docker.new() - local res = dk.images:inspect({name = tag}) - - if res.code == 200 then - local tags = res.body.RepoTags - if #tags > 1 then - local r = dk.images:remove({name = tag}) - local msg = r and r.body and r.body.message or nil - luci.http.status(r.code, msg) - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg}) - else - luci.http.status(500, "Cannot remove the last tag") - luci.http.prepare_content("application/json") - luci.http.write_json({message = "Cannot remove the last tag"}) - end - else - local msg = res and res.body and res.body.message or nil - luci.http.status(res and res.code or 500, msg or "unknow") - luci.http.prepare_content("application/json") - luci.http.write_json({message = msg or "unknow"}) - end -end diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua deleted file mode 100755 index f62650fe5..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua +++ /dev/null @@ -1,152 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2021 Florian Eckert -Copyright 2021 lisaac -]]-- - -local uci = (require "luci.model.uci").cursor() - -local m, s, o - -m = Map("dockerd", - translate("Docker - Configuration"), - translate("DockerMan is a simple docker manager client for LuCI")) - -if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - s = m:section(NamedSection, "globals", "section", translate("Docker Daemon settings")) - - o = s:option(Flag, "auto_start", translate("Auto start")) - o.rmempty = false - o.write = function(self, section, value) - if value == "1" then - luci.util.exec("/etc/init.d/dockerd enable") - else - luci.util.exec("/etc/init.d/dockerd disable") - end - m.uci:set("dockerd", "globals", "auto_start", value) - end - - o = s:option(Value, "data_root", - translate("Docker Root Dir")) - o.placeholder = "/opt/docker/" - o:depends("remote_endpoint", 0) - - o = s:option(Value, "bip", - translate("Default bridge"), - translate("Configure the default bridge network")) - o.placeholder = "172.17.0.1/16" - o.datatype = "ipaddr" - o:depends("remote_endpoint", 0) - - o = s:option(DynamicList, "registry_mirrors", - translate("Registry Mirrors"), - translate("It replaces the daemon registry mirrors with a new set of registry mirrors")) - o:value("https://hub-mirror.c.163.com", "https://hub-mirror.c.163.com") - o:depends("remote_endpoint", 0) - o.forcewrite = true - - o = s:option(ListValue, "log_level", - translate("Log Level"), - translate('Set the logging level')) - o:value("debug", translate("Debug")) - o:value("", translate("Info")) -- This is the default debug level from the deamon is optin is not set - o:value("warn", translate("Warning")) - o:value("error", translate("Error")) - o:value("fatal", translate("Fatal")) - o.rmempty = true - o:depends("remote_endpoint", 0) - - o = s:option(DynamicList, "hosts", - translate("Client connection"), - translate('Specifies where the Docker daemon will listen for client connections (default: unix:///var/run/docker.sock)')) - o:value("unix:///var/run/docker.sock", "unix:///var/run/docker.sock") - o:value("tcp://0.0.0.0:2375", "tcp://0.0.0.0:2375") - o.rmempty = true - o:depends("remote_endpoint", 0) -end - -s = m:section(NamedSection, "dockerman", "section", translate("DockerMan settings")) -s:tab("ac", translate("Access Control")) -s:tab("dockerman", translate("DockerMan")) - -o = s:taboption("dockerman", Flag, "remote_endpoint", - translate("Remote Endpoint"), - translate("Connect to remote docker endpoint")) -o.rmempty = false -o.validate = function(self, value, sid) - local res = luci.http.formvaluetable("cbid.dockerd") - if res["dockerman.remote_endpoint"] == "1" then - if res["dockerman.remote_port"] and res["dockerman.remote_port"] ~= "" and res["dockerman.remote_host"] and res["dockerman.remote_host"] ~= "" then - return 1 - else - return nil, translate("Please input the PORT or HOST IP of remote docker instance!") - end - else - if not res["dockerman.socket_path"] then - return nil, translate("Please input the SOCKET PATH of docker daemon!") - end - end - return 0 -end - -o = s:taboption("dockerman", Value, "socket_path", - translate("Docker Socket Path")) -o.default = "/var/run/docker.sock" -o.placeholder = "/var/run/docker.sock" -o:depends("remote_endpoint", 0) - -o = s:taboption("dockerman", Value, "remote_host", - translate("Remote Host"), - translate("Host or IP Address for the connection to a remote docker instance")) -o.datatype = "host" -o.placeholder = "10.1.1.2" -o:depends("remote_endpoint", 1) - -o = s:taboption("dockerman", Value, "remote_port", - translate("Remote Port")) -o.placeholder = "2375" -o.datatype = "port" -o:depends("remote_endpoint", 1) - --- o = s:taboption("dockerman", Value, "status_path", translate("Action Status Tempfile Path"), translate("Where you want to save the docker status file")) --- o = s:taboption("dockerman", Flag, "debug", translate("Enable Debug"), translate("For debug, It shows all docker API actions of luci-app-dockerman in Debug Tempfile Path")) --- o.enabled="true" --- o.disabled="false" --- o = s:taboption("dockerman", Value, "debug_path", translate("Debug Tempfile Path"), translate("Where you want to save the debug tempfile")) - -if nixio.fs.access("/usr/bin/dockerd") and not m.uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - o = s:taboption("ac", DynamicList, "ac_allowed_interface", translate("Allowed access interfaces"), translate("Which interface(s) can access containers under the bridge network, fill-in Interface Name")) - local interfaces = luci.sys and luci.sys.net and luci.sys.net.devices() or {} - for i, v in ipairs(interfaces) do - o:value(v, v) - end - o = s:taboption("ac", DynamicList, "ac_allowed_ports", translate("Ports allowed to be accessed"), translate("Which Port(s) can be accessed, it's not restricted by the Allowed Access interfaces configuration. Use this configuration with caution!")) - o.placeholder = "8080/tcp" - 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 then - for i, v in ipairs(containers) do - if v.State == "running" and v.Ports then - for _, port in ipairs(v.Ports) do - if port.PublicPort and port.IP and not string.find(port.IP,":") then - o:value(port.PublicPort.."/"..port.Type, v.Names[1]:sub(2) .. " | " .. port.PublicPort .. " | " .. port.Type) - end - end - end - end - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua deleted file mode 100755 index 20220ad8f..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua +++ /dev/null @@ -1,810 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -require "luci.util" - -local docker = require "luci.model.docker" -local dk = docker.new() - -container_id = arg[1] -local action = arg[2] or "info" - -local m, s, o -local images, networks, container_info, res - -if not container_id then - return -end - -res = dk.containers:inspect({id = container_id}) -if res.code < 300 then - container_info = res.body -else - return -end - -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 .. "
") or "") .. out[1]["HostPort"] .. ":" .. inter - end - end - - return data -end - -local get_env = function(d) - local data - - if d.Config and d.Config.Env then - for _,v in ipairs(d.Config.Env) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_command = function(d) - local data - - if d.Config and d.Config.Cmd then - for _,v in ipairs(d.Config.Cmd) do - data = (data and (data .. " ") or "") .. v - end - end - - return data -end - -local get_mounts = function(d) - local data - - if d.Mounts then - for _,v in ipairs(d.Mounts) do - local v_sorce_d, v_dest_d - local v_sorce = "" - local v_dest = "" - for v_sorce_d in v["Source"]:gmatch('[^/]+') do - if v_sorce_d and #v_sorce_d > 12 then - v_sorce = v_sorce .. "/" .. v_sorce_d:sub(1,12) .. "..." - else - v_sorce = v_sorce .."/".. v_sorce_d - end - end - for v_dest_d in v["Destination"]:gmatch('[^/]+') do - if v_dest_d and #v_dest_d > 12 then - v_dest = v_dest .. "/" .. v_dest_d:sub(1,12) .. "..." - else - v_dest = v_dest .."/".. v_dest_d - end - end - data = (data and (data .. "
") or "") .. v_sorce .. ":" .. v["Destination"] .. (v["Mode"] ~= "" and (":" .. v["Mode"]) or "") - end - end - - return data -end - -local get_device = function(d) - local data - - if d.HostConfig and d.HostConfig.Devices then - for _,v in ipairs(d.HostConfig.Devices) do - data = (data and (data .. "
") or "") .. v["PathOnHost"] .. ":" .. v["PathInContainer"] .. (v["CgroupPermissions"] ~= "" and (":" .. v["CgroupPermissions"]) or "") - end - end - - return data -end - -local get_links = function(d) - local data - - if d.HostConfig and d.HostConfig.Links then - for _,v in ipairs(d.HostConfig.Links) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_tmpfs = function(d) - local data - - if d.HostConfig and d.HostConfig.Tmpfs then - for k, v in pairs(d.HostConfig.Tmpfs) do - data = (data and (data .. "
") or "") .. k .. (v~="" and ":" or "")..v - end - end - - return data -end - -local get_dns = function(d) - local data - - if d.HostConfig and d.HostConfig.Dns then - for _, v in ipairs(d.HostConfig.Dns) do - data = (data and (data .. "
") or "") .. v - end - end - - return data -end - -local get_sysctl = function(d) - local data - - if d.HostConfig and d.HostConfig.Sysctls then - for k, v in pairs(d.HostConfig.Sysctls) do - data = (data and (data .. "
") or "") .. k..":"..v - end - end - - return data -end - -local get_networks = function(d) - local data={} - - if d.NetworkSettings and d.NetworkSettings.Networks and type(d.NetworkSettings.Networks) == "table" then - for k,v in pairs(d.NetworkSettings.Networks) do - data[k] = v.IPAddress or "" - end - end - - return data -end - - -local start_stop_remove = function(m, cmd) - local res - - docker:clear_status() - docker:append_status("Containers: " .. cmd .. " " .. container_id .. "...") - - if cmd ~= "upgrade" then - res = dk.containers[cmd](dk, {id = container_id}) - else - res = dk.containers_upgrade(dk, {id = container_id}) - end - - if res and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id)) - else - docker:clear_status() - if cmd ~= "remove" and cmd ~= "upgrade" then - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id)) - else - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - end - end -end - -m=SimpleForm("docker", - translatef("Docker - Container (%s)", container_info.Name:sub(2)), - translate("On this page, the selected container can be managed.")) -m.redirect = luci.dispatcher.build_url("admin/docker/containers") - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template = "cbi/nullsection" - -o = s:option(Button, "_start") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Start") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"start") -end - -o = s:option(Button, "_restart") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Restart") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"restart") -end - -o = s:option(Button, "_stop") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Stop") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"stop") -end - -o = s:option(Button, "_kill") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Kill") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"kill") -end - -o = s:option(Button, "_export") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Export") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container_export/"..container_id)) -end - -o = s:option(Button, "_upgrade") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Upgrade") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"upgrade") -end - -o = s:option(Button, "_duplicate") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Duplicate/Edit") -o.inputstyle = "add" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer/duplicate/"..container_id)) -end - -o = s:option(Button, "_remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle=translate("Remove") -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"remove") -end - -s = m:section(SimpleSection) -s.template = "dockerman/container" - -if action == "info" then - res = dk.networks:list() - if res.code < 300 then - networks = res.body - else - return - end - m.submit = false - m.reset = false - table_info = { - ["01name"] = { - _key = translate("Name"), - _value = container_info.Name:sub(2) or "-", - _button=translate("Update") - }, - ["02id"] = { - _key = translate("ID"), - _value = container_info.Id or "-" - }, - ["03image"] = { - _key = translate("Image"), - _value = container_info.Config.Image .. "
" .. container_info.Image - }, - ["04status"] = { - _key = translate("Status"), - _value = container_info.State and container_info.State.Status or "-" - }, - ["05created"] = { - _key = translate("Created"), - _value = container_info.Created or "-" - }, - } - - if container_info.State.Status == "running" then - table_info["06start"] = { - _key = translate("Start Time"), - _value = container_info.State and container_info.State.StartedAt or "-" - } - else - table_info["06start"] = { - _key = translate("Finish Time"), - _value = container_info.State and container_info.State.FinishedAt or "-" - } - end - - table_info["07healthy"] = { - _key = translate("Healthy"), - _value = container_info.State and container_info.State.Health and container_info.State.Health.Status or "-" - } - table_info["08restart"] = { - _key = translate("Restart Policy"), - _value = container_info.HostConfig and container_info.HostConfig.RestartPolicy and container_info.HostConfig.RestartPolicy.Name or "-", - _button=translate("Update") - } - table_info["081user"] = { - _key = translate("User"), - _value = container_info.Config and (container_info.Config.User ~="" and container_info.Config.User or "-") or "-" - } - table_info["09mount"] = { - _key = translate("Mount/Volume"), - _value = get_mounts(container_info) or "-" - } - table_info["10cmd"] = { - _key = translate("Command"), - _value = get_command(container_info) or "-" - } - table_info["11env"] = { - _key = translate("Env"), - _value = get_env(container_info) or "-" - } - table_info["12ports"] = { - _key = translate("Ports"), - _value = get_ports(container_info) or "-" - } - table_info["13links"] = { - _key = translate("Links"), - _value = get_links(container_info) or "-" - } - table_info["14device"] = { - _key = translate("Device"), - _value = get_device(container_info) or "-" - } - table_info["15tmpfs"] = { - _key = translate("Tmpfs"), - _value = get_tmpfs(container_info) or "-" - } - table_info["16dns"] = { - _key = translate("DNS"), - _value = get_dns(container_info) or "-" - } - table_info["17sysctl"] = { - _key = translate("Sysctl"), - _value = get_sysctl(container_info) or "-" - } - - info_networks = get_networks(container_info) - list_networks = {} - for _, v in ipairs (networks) do - if v and v.Name then - local parent = v.Options and v.Options.parent or nil - local ip = v.IPAM and v.IPAM.Config and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - ipv6 = v.IPAM and v.IPAM.Config and v.IPAM.Config[2] and v.IPAM.Config[2].Subnet or nil - local network_name = v.Name .. " | " .. v.Driver .. (parent and (" | " .. parent) or "") .. (ip and (" | " .. ip) or "").. (ipv6 and (" | " .. ipv6) or "") - list_networks[v.Name] = network_name - end - end - - if type(info_networks)== "table" then - for k,v in pairs(info_networks) do - table_info["14network"..k] = { - _key = translate("Network"), - _value = k.. (v~="" and (" | ".. v) or ""), - _button=translate("Disconnect") - } - list_networks[k]=nil - end - end - - table_info["15connect"] = { - _key = translate("Connect Network"), - _value = list_networks ,_opts = "", - _button=translate("Connect") - } - - s = m:section(Table,table_info) - s.nodescr=true - s.formvalue=function(self, section) - return table_info - end - - o = s:option(DummyValue, "_key", translate("Info")) - o.width = "20%" - - o = s:option(ListValue, "_value") - o.render = function(self, section, scope) - if table_info[section]._key == translate("Name") then - self:reset_values() - self.template = "cbi/value" - self.size = 30 - self.keylist = {} - self.vallist = {} - self.default=table_info[section]._value - Value.render(self, section, scope) - elseif table_info[section]._key == translate("Restart Policy") then - self.template = "cbi/lvalue" - self:reset_values() - self.size = nil - self:value("no", "No") - self:value("unless-stopped", "Unless stopped") - self:value("always", "Always") - self:value("on-failure", "On failure") - self.default=table_info[section]._value - ListValue.render(self, section, scope) - elseif table_info[section]._key == translate("Connect Network") then - self.template = "cbi/lvalue" - self:reset_values() - self.size = nil - for k,v in pairs(list_networks) do - if k ~= "host" then - self:value(k,v) - end - end - self.default=table_info[section]._value - ListValue.render(self, section, scope) - else - self:reset_values() - self.rawhtml=true - self.template = "cbi/dvalue" - self.default=table_info[section]._value - DummyValue.render(self, section, scope) - end - end - o.forcewrite = true - o.write = function(self, section, value) - table_info[section]._value=value - end - o.validate = function(self, value) - return value - end - - o = s:option(Value, "_opts") - o.forcewrite = true - o.write = function(self, section, value) - table_info[section]._opts=value - end - o.validate = function(self, value) - return value - end - o.render = function(self, section, scope) - if table_info[section]._key==translate("Connect Network") then - self.template = "cbi/value" - self.keylist = {} - self.vallist = {} - self.placeholder = "10.1.1.254" - self.datatype = "ip4addr" - self.default=table_info[section]._opts - Value.render(self, section, scope) - else - self.rawhtml=true - self.template = "cbi/dvalue" - self.default=table_info[section]._opts - DummyValue.render(self, section, scope) - end - end - - o = s:option(Button, "_button") - o.forcewrite = true - o.render = function(self, section, scope) - if table_info[section]._button and table_info[section]._value ~= nil then - self.inputtitle=table_info[section]._button - self.template = "cbi/button" - self.inputstyle = "edit" - Button.render(self, section, scope) - else - self.template = "cbi/dvalue" - self.default="" - DummyValue.render(self, section, scope) - end - end - o.write = function(self, section, value) - local res - - docker:clear_status() - - if section == "01name" then - docker:append_status("Containers: rename " .. container_id .. "...") - local new_name = table_info[section]._value - res = dk.containers:rename({ - id = container_id, - query = { - name=new_name - } - }) - elseif section == "08restart" then - docker:append_status("Containers: update " .. container_id .. "...") - local new_restart = table_info[section]._value - res = dk.containers:update({ - id = container_id, - body = { - RestartPolicy = { - Name = new_restart - } - } - }) - elseif table_info[section]._key == translate("Network") then - local _,_,leave_network - - _, _, leave_network = table_info[section]._value:find("(.-) | .+") - leave_network = leave_network or table_info[section]._value - docker:append_status("Network: disconnect " .. leave_network .. container_id .. "...") - res = dk.networks:disconnect({ - name = leave_network, - body = { - Container = container_id - } - }) - elseif section == "15connect" then - local connect_network = table_info[section]._value - local network_opiton - if connect_network ~= "none" - and connect_network ~= "bridge" - and connect_network ~= "host" then - - network_opiton = table_info[section]._opts ~= "" and { - IPAMConfig={ - IPv4Address=table_info[section]._opts - } - } or nil - end - docker:append_status("Network: connect " .. connect_network .. container_id .. "...") - res = dk.networks:connect({ - name = connect_network, - body = { - Container = container_id, - EndpointConfig= network_opiton - } - }) - end - - if res and res.code > 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - else - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id.."/info")) - end -elseif action == "resources" then - s = m:section(SimpleSection) - o = s:option( Value, "cpus", - translate("CPUs"), - translate("Number of CPUs. Number is a fractional number. 0.000 means no limit.")) - o.placeholder = "1.5" - o.rmempty = true - o.datatype="ufloat" - o.default = container_info.HostConfig.NanoCpus / (10^9) - - o = s:option(Value, "cpushares", - 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.")) - o.placeholder = "1024" - o.rmempty = true - o.datatype="uinteger" - o.default = container_info.HostConfig.CpuShares - - o = s:option(Value, "memory", - translate("Memory"), - translate("Memory limit (format: []). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M.")) - o.placeholder = "128m" - o.rmempty = true - o.default = container_info.HostConfig.Memory ~=0 and ((container_info.HostConfig.Memory / 1024 /1024) .. "M") or 0 - - o = s:option(Value, "blkioweight", - translate("Block IO Weight"), - translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000.")) - o.placeholder = "500" - o.rmempty = true - o.datatype="uinteger" - o.default = container_info.HostConfig.BlkioWeight - - m.handle = function(self, state, data) - if state == FORM_VALID then - local memory = data.memory - if memory and memory ~= 0 then - _,_,n,unit = memory:find("([%d%.]+)([%l%u]+)") - if n then - unit = unit and unit:sub(1,1):upper() or "B" - if unit == "M" then - memory = tonumber(n) * 1024 * 1024 - elseif unit == "G" then - memory = tonumber(n) * 1024 * 1024 * 1024 - elseif unit == "K" then - memory = tonumber(n) * 1024 - else - memory = tonumber(n) - end - end - end - - request_body = { - BlkioWeight = tonumber(data.blkioweight), - NanoCPUs = tonumber(data.cpus)*10^9, - Memory = tonumber(memory), - CpuShares = tonumber(data.cpushares) - } - - docker:write_status("Containers: update " .. container_id .. "...") - local res = dk.containers:update({id = container_id, body = request_body}) - if res and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - else - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/container/"..container_id.."/resources")) - end - end - -elseif action == "file" then - m.submit = false - m.reset = false - s= m:section(SimpleSection) - s.template = "dockerman/container_file_manager" - s.container = container_id - m.redirect = nil -elseif action == "inspect" then - s = m:section(SimpleSection) - s.syslog = luci.jsonc.stringify(container_info, true) - s.title = translate("Container Inspect") - s.template = "dockerman/logs" - m.submit = false - m.reset = false -elseif action == "logs" then - local logs = "" - local query ={ - stdout = 1, - stderr = 1, - tail = 1000 - } - - s = m:section(SimpleSection) - - logs = dk.containers:logs({id = container_id, query = query}) - if logs.code == 200 then - s.syslog=logs.body - else - s.syslog="Get Logs ERROR\n"..logs.code..": "..logs.body - end - - s.title=translate("Container Logs") - s.template = "dockerman/logs" - m.submit = false - m.reset = false -elseif action == "console" then - m.submit = false - m.reset = false - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil - - if cmd_docker and cmd_ttyd and container_info.State.Status == "running" then - local cmd = "/bin/sh" - local uid - - s = m:section(SimpleSection) - - o = s:option(Value, "command", translate("Command")) - o:value("/bin/sh", "/bin/sh") - o:value("/bin/ash", "/bin/ash") - o:value("/bin/bash", "/bin/bash") - o.default = "/bin/sh" - o.forcewrite = true - o.write = function(self, section, value) - cmd = value - end - - o = s:option(Value, "uid", translate("UID")) - o.forcewrite = true - o.write = function(self, section, value) - uid = value - end - - o = s:option(Button, "connect") - o.render = function(self, section, scope) - self.inputstyle = "add" - self.title = " " - self.inputtitle = translate("Connect") - Button.render(self, section, scope) - end - o.write = function(self, section) - local cmd_docker = luci.util.exec("command -v docker"):match("^.+docker") or nil - local cmd_ttyd = luci.util.exec("command -v ttyd"):match("^.+ttyd") or nil - - if not cmd_docker or not cmd_ttyd or cmd_docker:match("^%s+$") or cmd_ttyd:match("^%s+$") then - return - end - local uci = (require "luci.model.uci").cursor() - - local ttyd_ssl = uci:get("ttyd", "@ttyd[0]", "ssl") - local ttyd_ssl_key = uci:get("ttyd", "@ttyd[0]", "ssl_key") - local ttyd_ssl_cert = uci:get("ttyd", "@ttyd[0]", "ssl_cert") - - if ttyd_ssl == "1" and ttyd_ssl_cert and ttyd_ssl_key then - cmd_ttyd = string.format('%s -S -C %s -K %s', cmd_ttyd, ttyd_ssl_cert, ttyd_ssl_key) - end - - local pid = luci.util.trim(luci.util.exec("netstat -lnpt | grep :7682 | grep ttyd | tr -s ' ' | cut -d ' ' -f7 | cut -d'/' -f1")) - if pid and pid ~= "" then - luci.util.exec("kill -9 " .. pid) - end - - local hosts - local remote = uci:get_bool("dockerd", "dockerman", "remote_endpoint") or false - local host = nil - local port = nil - local socket = nil - - if remote then - host = uci:get("dockerd", "dockerman", "remote_host") or nil - port = uci:get("dockerd", "dockerman", "remote_port") or nil - else - socket = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - end - - if remote and host and port then - hosts = "tcp://" .. host .. ':'.. port - elseif socket then - hosts = "unix://" .. socket - else - return - end - - if uid and uid ~= "" then - uid = "-u " .. uid - else - uid = "" - end - - local start_cmd = string.format('%s -d 2 --once -p 7682 %s -H "%s" exec -it %s %s %s&', cmd_ttyd, cmd_docker, hosts, uid, container_id, cmd) - - os.execute(start_cmd) - - o = s:option(DummyValue, "console") - o.container_id = container_id - o.template = "dockerman/container_console" - end - end -elseif action == "stats" then - local response = dk.containers:top({id = container_id, query = {ps_args="-aux"}}) - local container_top - - if response.code == 200 then - container_top=response.body - else - response = dk.containers:top({id = container_id}) - if response.code == 200 then - container_top=response.body - end - end - - if type(container_top) == "table" then - s = m:section(SimpleSection) - s.container_id = container_id - s.template = "dockerman/container_stats" - table_stats = { - cpu={ - key=translate("CPU Useage"), - value='-' - }, - memory={ - key=translate("Memory Useage"), - value='-' - } - } - - container_top = response.body - s = m:section(Table, table_stats, translate("Stats")) - s:option(DummyValue, "key", translate("Stats")).width="33%" - s:option(DummyValue, "value") - top_section = m:section(Table, container_top.Processes, translate("TOP")) - for i, v in ipairs(container_top.Titles) do - top_section:option(DummyValue, i, translate(v)) - end - end - - m.submit = false - m.reset = false -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua deleted file mode 100755 index 47f634f8b..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua +++ /dev/null @@ -1,284 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local http = require "luci.http" -local docker = require "luci.model.docker" - -local m, s, o -local images, networks, containers, res, lost_state -local urlencode = luci.http.protocol and luci.http.protocol.urlencode or luci.util.urlencode -local dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.images:list() - if res and res.code and res.code < 300 then - images = res.body - end - - res = dk.networks:list() - if res and res.code and res.code < 300 then - networks = res.body - end - - res = dk.containers:list({ - query = { - all = true - } - }) - if res and res.code and res.code < 300 then - containers = res.body - end -end - -function get_containers() - local data = {} - if type(containers) ~= "table" then - return nil - end - - for i, v in ipairs(containers) do - local index = (10^12 - v.Created) .. "_id_" .. 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]["_status"] = v.Status - - if v.Status:find("^Up") then - data[index]["_name"] = ""..v.Names[1]:sub(2).."" - data[index]["_status"] = "".. data[index]["_status"] .. "" .. "


" - else - data[index]["_name"] = ""..v.Names[1]:sub(2).."" - data[index]["_status"] = ''.. data[index]["_status"] .. "" - 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 - local ip = require "luci.ip" - for _,v2 in ipairs(v.Ports) do - -- display ipv4 only - if ip.new(v2.IP or "0.0.0.0"):is4() then - data[index]["_ports"] = (data[index]["_ports"] and (data[index]["_ports"] .. ", ") or "") - .. ((v2.PublicPort and v2.Type and v2.Type == "tcp") and ('') 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 "" or "") - end - 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]["_id_name"] = ''.. data[index]["_name"] .. "
ID: " .. data[index]["_id"] - .. "

Image: " .. (data[index]["_image"] or "<none>") - .. "
" - - if type(v.Mounts) == "table" and next(v.Mounts) then - for _, v2 in pairs(v.Mounts) do - if v2.Type ~= "volume" then - local v_sorce_d, v_dest_d - local v_sorce = "" - local v_dest = "" - for v_sorce_d in v2["Source"]:gmatch('[^/]+') do - if v_sorce_d and #v_sorce_d > 12 then - v_sorce = v_sorce .. "/" .. v_sorce_d:sub(1,8) .. ".." - else - v_sorce = v_sorce .."/".. v_sorce_d - end - end - for v_dest_d in v2["Destination"]:gmatch('[^/]+') do - if v_dest_d and #v_dest_d > 12 then - v_dest = v_dest .. "/" .. v_dest_d:sub(1,8) .. ".." - else - v_dest = v_dest .."/".. v_dest_d - end - end - data[index]["_mounts"] = (data[index]["_mounts"] and (data[index]["_mounts"] .. "
") or "") .. '' .. v_sorce .. "→" .. v_dest..'' - end - end - end - - data[index]["_image_id"] = v.ImageID:sub(8,20) - data[index]["_command"] = v.Command - end - return data -end - -local container_list = not lost_state and get_containers() or {} - -m = SimpleForm("docker", - translate("Docker - Containers"), - translate("This page displays all containers that have been created on the connected docker host.")) -m.submit=false -m.reset=false -m:append(Template("dockerman/containers_running_stats")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table, container_list, translate("Containers")) -s.nodescr=true -s.config="containers" - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.width = "1%" -o.write=function(self, section, value) - container_list[section]._selected = value -end - --- o = s:option(DummyValue, "_id", translate("ID")) --- o.width="10%" - --- o = s:option(DummyValue, "_name", translate("Container Name")) --- o.rawhtml = true - -o = s:option(DummyValue, "_id_name", translate("Container Info")) -o.rawhtml = true -o.width="15%" - -o = s:option(DummyValue, "_status", translate("Status")) -o.width="15%" -o.rawhtml=true - -o = s:option(DummyValue, "_network", translate("Network")) -o.width="10%" - -o = s:option(DummyValue, "_ports", translate("Ports")) -o.width="5%" -o.rawhtml = true -o = s:option(DummyValue, "_mounts", translate("Mounts")) -o.width="25%" -o.rawhtml = true - --- o = s:option(DummyValue, "_image", translate("Image")) --- o.width="8%" - -o = s:option(DummyValue, "_command", translate("Command")) -o.width="15%" - -local start_stop_remove = function(m, cmd) - local container_selected = {} - -- 遍历table中sectionid - for k in pairs(container_list) do - -- 得到选中项的名字 - if container_list[k]._selected == 1 then - container_selected[#container_selected + 1] = container_list[k]["_id"] - end - end - if #container_selected > 0 then - local success = true - - docker:clear_status() - for _, cont in ipairs(container_selected) do - docker:append_status("Containers: " .. cmd .. " " .. cont .. "...") - local res = dk.containers[cmd](dk, {id = cont}) - if res and res.code 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 - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "_new") -o.inputtitle = translate("Add") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "add" -o.forcewrite = true -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) -end -o.disable = lost_state - -o = s:option(Button, "_start") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Start") -o.inputstyle = "apply" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"start") -end -o.disable = lost_state - -o = s:option(Button, "_restart") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Restart") -o.inputstyle = "reload" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"restart") -end -o.disable = lost_state - -o = s:option(Button, "_stop") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Stop") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"stop") -end -o.disable = lost_state - -o = s:option(Button, "_kill") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Kill") -o.inputstyle = "reset" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m,"kill") -end -o.disable = lost_state - -o = s:option(Button, "_remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputtitle = translate("Remove") -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - start_stop_remove(m, "remove") -end -o.disable = lost_state - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua deleted file mode 100755 index c3d3eab0d..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua +++ /dev/null @@ -1,284 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local dk = docker.new() - -local containers, images, res, lost_state -local m, s, o - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.images:list() - if res and res.code and res.code < 300 then - images = res.body - end - - res = dk.containers:list({ query = { all = true } }) - if res and res.code and res.code < 300 then - containers = res.body - end -end - -function get_images() - local data = {} - - for i, v in ipairs(images) do - local index = v.Created .. v.Id - - data[index]={} - data[index]["_selected"] = 0 - data[index]["id"] = v.Id:sub(8) - data[index]["_id"] = '' .. v.Id:sub(8,20) .. '' - - if v.RepoTags and next(v.RepoTags)~=nil then - for i, v1 in ipairs(v.RepoTags) do - data[index]["_tags"] =(data[index]["_tags"] and ( data[index]["_tags"] .. "
" )or "") .. ((v1:match("") or (#v.RepoTags == 1)) and v1 or ('' .. v1 .. '')) - - if not data[index]["tag"] then - data[index]["tag"] = v1 - end - end - else - data[index]["_tags"] = v.RepoDigests[1] and v.RepoDigests[1]:match("^(.-)@.+") - data[index]["_tags"] = (data[index]["_tags"] and data[index]["_tags"] or "" ).. ":" - end - - data[index]["_tags"] = data[index]["_tags"]:gsub("","<none>") - for ci,cv in ipairs(containers) do - if v.Id == cv.ImageID then - data[index]["_containers"] = (data[index]["_containers"] and (data[index]["_containers"] .. " | ") or "").. - ''.. cv.Names[1]:sub(2).."" - end - end - - data[index]["_size"] = string.format("%.2f", tostring(v.Size/1024/1024)).."MB" - data[index]["_created"] = os.date("%Y/%m/%d %H:%M:%S",v.Created) - end - - return data -end - -local image_list = not lost_state and get_images() or {} - -m = SimpleForm("docker", - translate("Docker - Images"), - translate("On this page all images are displayed that are available on the system and with which a container can be created.")) -m.submit=false -m.reset=false - -local pull_value={ - _image_tag_name="", - _registry="index.docker.io" -} - -s = m:section(SimpleSection, - translate("Pull Image"), - translate("By entering a valid image name with the corresponding version, the docker image can be downloaded from the configured registry.")) -s.template="cbi/nullsection" - -o = s:option(Value, "_image_tag_name") -o.template = "dockerman/cbi/inlinevalue" -o.placeholder="lisaac/luci:latest" -o.write = function(self, section, value) - local hastag = value:find(":") - - if not hastag then - value = value .. ":latest" - end - pull_value["_image_tag_name"] = value -end - -o = s:option(Button, "_pull") -o.inputtitle= translate("Pull") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "add" -o.disable = lost_state -o.write = function(self, section) - local tag = pull_value["_image_tag_name"] - local json_stringify = luci.jsonc and luci.jsonc.stringify - - if tag and tag ~= "" then - docker:write_status("Images: " .. "pulling" .. " " .. tag .. "...\n") - local res = dk.images:create({query = {fromImage=tag}}, docker.pull_image_show_status_cb) - - if res and res.code and res.code == 200 and (res.body[#res.body] and not res.body[#res.body].error and res.body[#res.body].status and (res.body[#res.body].status == "Status: Downloaded newer image for ".. tag)) then - docker:clear_status() - else - docker:append_status("code:" .. res.code.." ".. (res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)).. "\n") - end - else - docker:append_status("code: 400 please input the name of image name!") - end - - luci.http.redirect(luci.dispatcher.build_url("admin/docker/images")) -end - -s = m:section(SimpleSection, - translate("Import Image"), - translate("When pressing the Import button, both a local image can be loaded onto the system and a valid image tar can be downloaded from remote.")) - -o = s:option(DummyValue, "_image_import") -o.template = "dockerman/images_import" -o.disable = lost_state - -s = m:section(Table, image_list, translate("Images overview")) - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.write = function(self, section, value) - image_list[section]._selected = value -end - -o = s:option(DummyValue, "_id", translate("ID")) -o.rawhtml = true - -o = s:option(DummyValue, "_tags", translate("RepoTags")) -o.rawhtml = true - -o = s:option(DummyValue, "_containers", translate("Containers")) -o.rawhtml = true - -o = s:option(DummyValue, "_size", translate("Size")) - -o = s:option(DummyValue, "_created", translate("Created")) - -local remove_action = function(force) - local image_selected = {} - - for k in pairs(image_list) do - if image_list[k]._selected == 1 then - image_selected[#image_selected+1] = (image_list[k]["_tags"]:match("
") or image_list[k]["_tags"]:match("<none>")) and image_list[k].id or image_list[k].tag - end - end - - if next(image_selected) ~= nil then - local success = true - - docker:clear_status() - for _, img in ipairs(image_selected) do - local query - docker:append_status("Images: " .. "remove" .. " " .. img .. "...") - - if force then - query = {force = true} - end - - local msg = dk.images:remove({ - id = img, - query = query - }) - if msg and msg.code ~= 200 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - success = false - else - docker:append_status("done\n") - end - end - - if success then - docker:clear_status() - end - - luci.http.redirect(luci.dispatcher.build_url("admin/docker/images")) - end -end - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err = docker:read_status() -s.err = s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - remove_action() -end -o.disable = lost_state - -o = s:option(Button, "forceremove") -o.inputtitle= translate("Force Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.write = function(self, section) - remove_action(true) -end -o.disable = lost_state - -o = s:option(Button, "save") -o.inputtitle= translate("Save") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "edit" -o.disable = lost_state -o.forcewrite = true -o.write = function (self, section) - local image_selected = {} - - for k in pairs(image_list) do - if image_list[k]._selected == 1 then - image_selected[#image_selected + 1] = image_list[k].id - end - end - - if next(image_selected) ~= nil then - local names, first, show_name - - for _, img in ipairs(image_selected) do - names = names and (names .. "&names=".. img) or img - end - if #image_selected > 1 then - show_name = "images" - else - show_name = image_selected[1] - end - local cb = function(res, chunk) - if res and res.code and res.code == 200 then - if not first then - first = true - luci.http.header('Content-Disposition', 'inline; filename="'.. show_name .. '.tar"') - luci.http.header('Content-Type', 'application\/x-tar') - end - luci.ltn12.pump.all(chunk, luci.http.write) - else - if not first then - first = true - luci.http.prepare_content("text/plain") - end - luci.ltn12.pump.all(chunk, luci.http.write) - end - end - - docker:write_status("Images: " .. "save" .. " " .. table.concat(image_selected, "\n") .. "...") - local msg = dk.images:get({query = {names = names}}, cb) - if msg and msg.code and msg.code ~= 200 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - else - docker:clear_status() - end - end -end - -o = s:option(Button, "load") -o.inputtitle= translate("Load") -o.template = "dockerman/images_load" -o.inputstyle = "add" -o.disable = lost_state - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua deleted file mode 100755 index 37702c783..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua +++ /dev/null @@ -1,159 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o -local networks, dk, res, lost_state - -dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.networks:list() - if res and res.code and res.code < 300 then - networks = res.body - end -end - -local get_networks = function () - local data = {} - - if type(networks) ~= "table" then - return nil - end - - for i, v in ipairs(networks) 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.Name - data[index]["_driver"] = v.Driver - - if v.Driver == "bridge" then - data[index]["_interface"] = v.Options["com.docker.network.bridge.name"] - elseif v.Driver == "macvlan" then - data[index]["_interface"] = v.Options.parent - end - - data[index]["_subnet"] = v.IPAM and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - data[index]["_gateway"] = v.IPAM and v.IPAM.Config[1] and v.IPAM.Config[1].Gateway or nil - end - - return data -end - -local network_list = not lost_state and get_networks() or {} - -m = SimpleForm("docker", - translate("Docker - Networks"), - translate("This page displays all docker networks that have been created on the connected docker host.")) -m.submit=false -m.reset=false - -s = m:section(Table, network_list, translate("Networks overview")) -s.nodescr=true - -o = s:option(Flag, "_selected","") -o.template = "dockerman/cbi/xfvalue" -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.render = function(self, section, scope) - self.disable = 0 - if network_list[section]["_name"] == "bridge" or network_list[section]["_name"] == "none" or network_list[section]["_name"] == "host" then - self.disable = 1 - end - Flag.render(self, section, scope) -end -o.write = function(self, section, value) - network_list[section]._selected = value -end - -o = s:option(DummyValue, "_id", translate("ID")) - -o = s:option(DummyValue, "_name", translate("Network Name")) - -o = s:option(DummyValue, "_driver", translate("Driver")) - -o = s:option(DummyValue, "_interface", translate("Parent Interface")) - -o = s:option(DummyValue, "_subnet", translate("Subnet")) - -o = s:option(DummyValue, "_gateway", translate("Gateway")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err = docker:read_status() -s.err = s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "_new") -o.inputtitle= translate("New") -o.template = "dockerman/cbi/inlinebutton" -o.notitle=true -o.inputstyle = "add" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newnetwork")) -end - -o = s:option(Button, "_remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - local network_selected = {} - local network_name_selected = {} - local network_driver_selected = {} - - for k in pairs(network_list) do - if network_list[k]._selected == 1 then - network_selected[#network_selected + 1] = network_list[k]._id - network_name_selected[#network_name_selected + 1] = network_list[k]._name - network_driver_selected[#network_driver_selected + 1] = network_list[k]._driver - end - end - - if next(network_selected) ~= nil then - local success = true - docker:clear_status() - - for ii, net in ipairs(network_selected) do - docker:append_status("Networks: " .. "remove" .. " " .. net .. "...") - local res = dk.networks["remove"](dk, {id = net}) - - if res and res.code and res.code >= 300 then - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - success = false - else - docker:append_status("done\n") - if network_driver_selected[ii] == "macvlan" then - docker.remove_macvlan_interface(network_name_selected[ii]) - end - end - end - - if success then - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/networks")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua deleted file mode 100755 index bfd1bf2a1..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua +++ /dev/null @@ -1,923 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o - -local dk = docker.new() - -local cmd_line = table.concat(arg, '/') -local images, networks -local create_body = {} - -if dk:_ping().code ~= 200 then - lost_state = true - images = {} - networks = {} -else - images = dk.images:list().body - networks = dk.networks:list().body -end - -local is_quot_complete = function(str) - local num = 0, w - require "math" - - if not str then - return true - end - - local num = 0, w - for w in str:gmatch("\"") do - num = num + 1 - end - - if math.fmod(num, 2) ~= 0 then - return false - end - - num = 0 - for w in str:gmatch("\'") do - num = num + 1 - end - - if math.fmod(num, 2) ~= 0 then - return false - end - - return true -end - -function contains(list, x) - for _, v in pairs(list) do - if v == x then - return true - end - end - return false -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', - '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', - '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_optiondns_search', - 'e', - 'env', - 'env_file', - 'expose', - 'group_add', - 'l', - 'label', - 'label_file', - 'link', - 'link_local_ip', - 'log_opt', - 'network_alias', - 'p', - 'publish', - 'security_opt', - 'storage_opt', - 'tmpfs', - 'v', - 'volume', - 'volumes_from', - } - - local key = nil - local _key = nil - local val = nil - local is_cmd = false - - cmd_line = cmd_line:match("^DOCKERCLI%s+(.+)") - for w in cmd_line:gmatch("[^%s]+") do - if w =='\\' then - elseif not key and not _key and not is_cmd then - --key=val - key, val = w:match("^%-%-([%lP%-]-)=(.+)") - if not key then - --key val - key = w:match("^%-%-([%lP%-]+)") - if not key then - -- -v val - key = w:match("^%-([%lP%-]+)") - if key then - -- for -dit - if key:match("i") or key:match("t") or key:match("d") then - if key:match("i") then - config[key_abb["i"]] = true - key:gsub("i", "") - end - if key:match("t") then - config[key_abb["t"]] = true - key:gsub("t", "") - end - if key:match("d") then - 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 - end - end - if key then - key = key:gsub("-","_") - key = key_abb[key] or key - if contains(key_no_val, key) then - config[key] = true - val = nil - key = nil - elseif contains(key_with_val, key) then - -- if key == "cap_add" then config.privileged = true end - else - key = nil - val = nil - end - else - config.image = w - key = nil - val = nil - is_cmd = true - end - elseif (key or _key) and not is_cmd then - if key == "mount" then - -- we need resolve mount options here - -- type=bind,source=/source,target=/app - local _type = w:match("^type=([^,]+),") or "bind" - local source = (_type ~= "tmpfs") and (w:match("source=([^,]+),") or w:match("src=([^,]+),")) or "" - local target = w:match(",target=([^,]+)") or w:match(",dst=([^,]+)") or w:match(",destination=([^,]+)") or "" - local ro = w:match(",readonly") and "ro" or nil - - if source and target then - if _type ~= "tmpfs" then - local bind_propagation = (_type == "bind") and w:match(",bind%-propagation=([^,]+)") or nil - val = source..":"..target .. ((ro or bind_propagation) and (":" .. (ro and ro or "") .. (((ro and bind_propagation) and "," or "") .. (bind_propagation and bind_propagation or ""))or "")) - else - local tmpfs_mode = w:match(",tmpfs%-mode=([^,]+)") or nil - local tmpfs_size = w:match(",tmpfs%-size=([^,]+)") or nil - key = "tmpfs" - val = target .. ((tmpfs_mode or tmpfs_size) and (":" .. (tmpfs_mode and ("mode=" .. tmpfs_mode) or "") .. ((tmpfs_mode and tmpfs_size) and "," or "") .. (tmpfs_size and ("size=".. tmpfs_size) or "")) or "") - if not config[key] then - config[key] = {} - end - table.insert( config[key], val ) - key = nil - val = nil - end - end - else - val = w - end - elseif is_cmd then - config["command"] = (config["command"] and (config["command"] .. " " )or "") .. w - end - if (key or _key) and val then - key = _key or key - if contains(key_with_list, key) then - if not config[key] then - config[key] = {} - end - if _key then - config[key][#config[key]] = config[key][#config[key]] .. " " .. w - else - table.insert( config[key], val ) - end - if is_quot_complete(config[key][#config[key]]) then - config[key][#config[key]] = config[key][#config[key]]:gsub("[\"\']", "") - _key = nil - else - _key = key - end - else - config[key] = (config[key] and (config[key] .. " ") or "") .. val - if is_quot_complete(config[key]) then - config[key] = config[key]:gsub("[\"\']", "") - _key = nil - else - _key = key - end - end - key = nil - val = nil - end - end - - return config -end - -local default_config = {} - -if cmd_line and cmd_line:match("^DOCKERCLI.+") then - default_config = resolve_cli(cmd_line) -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 {} - if not create_body.HostConfig then - create_body.HostConfig = {} - end - - if next(create_body) ~= nil then - default_config.name = nil - default_config.image = create_body.Image - default_config.hostname = create_body.Hostname - default_config.tty = create_body.Tty and true or false - default_config.interactive = create_body.OpenStdin and true or false - default_config.privileged = create_body.HostConfig.Privileged and true or false - default_config.restart = create_body.HostConfig.RestartPolicy and create_body.HostConfig.RestartPolicy.name or nil - -- default_config.network = create_body.HostConfig.NetworkMode == "default" and "bridge" or create_body.HostConfig.NetworkMode - -- if container has leave original network, and add new network, .HostConfig.NetworkMode is INcorrect, so using first child of .NetworkingConfig.EndpointsConfig - default_config.network = create_body.NetworkingConfig and create_body.NetworkingConfig.EndpointsConfig and next(create_body.NetworkingConfig.EndpointsConfig) or nil - default_config.ip = default_config.network and default_config.network ~= "bridge" and default_config.network ~= "host" and default_config.network ~= "null" and create_body.NetworkingConfig.EndpointsConfig[default_config.network].IPAMConfig and create_body.NetworkingConfig.EndpointsConfig[default_config.network].IPAMConfig.IPv4Address or nil - default_config.link = create_body.HostConfig.Links - default_config.env = create_body.Env - 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 = {} - for k, v in pairs(create_body.HostConfig.Sysctls) do - table.insert( default_config.sysctl, k.."="..v ) - end - end - if create_body.HostConfig.LogConfig then - if 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 - default_config.log_driver = create_body.HostConfig.LogConfig.Type or nil - 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 - for x, y in ipairs(v) do - table.insert( default_config.publish, y.HostPort..":"..k:match("^(%d+)/.+").."/"..k:match("^%d+/(.+)") ) - end - end - end - - default_config.user = create_body.User or nil - default_config.command = create_body.Cmd and type(create_body.Cmd) == "table" and table.concat(create_body.Cmd, " ") or nil - default_config.advance = 1 - default_config.cpus = create_body.HostConfig.NanoCPUs - default_config.cpu_shares = create_body.HostConfig.CpuShares - default_config.memory = create_body.HostConfig.Memory - default_config.blkio_weight = create_body.HostConfig.BlkioWeight - - if create_body.HostConfig.Devices and type(create_body.HostConfig.Devices) == "table" then - default_config.device = {} - for _, v in ipairs(create_body.HostConfig.Devices) do - table.insert( default_config.device, v.PathOnHost..":"..v.PathInContainer..(v.CgroupPermissions ~= "" and (":" .. v.CgroupPermissions) or "") ) - end - end - - if create_body.HostConfig.Tmpfs and type(create_body.HostConfig.Tmpfs) == "table" then - default_config.tmpfs = {} - for k, v in pairs(create_body.HostConfig.Tmpfs) do - table.insert( default_config.tmpfs, k .. (v~="" and ":" or "")..v ) - end - end - end -end - -m = SimpleForm("docker", translate("Docker - Containers")) -m.redirect = luci.dispatcher.build_url("admin", "docker", "containers") -if lost_state then - m.submit=false - m.reset=false -end - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(SimpleSection, translate("Create new docker container")) -s.addremove = true -s.anonymous = true - -o = s:option(DummyValue,"cmd_line", translate("Resolve CLI")) -o.rawhtml = true -o.template = "dockerman/newcontainer_resolve" - -o = s:option(Value, "name", translate("Container Name")) -o.rmempty = true -o.default = default_config.name or nil - -o = s:option(Flag, "interactive", translate("Interactive (-i)")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.interactive and 1 or 0 - -o = s:option(Flag, "tty", translate("TTY (-t)")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.tty and 1 or 0 - -o = s:option(Value, "image", translate("Docker Image")) -o.rmempty = true -o.default = default_config.image or nil -for _, v in ipairs (images) do - if v.RepoTags then - o:value(v.RepoTags[1], v.RepoTags[1]) - end -end - -o = s:option(Flag, "_force_pull", translate("Always pull image first")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -o = s:option(Flag, "privileged", translate("Privileged")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.privileged and 1 or 0 - -o = s:option(ListValue, "restart", translate("Restart Policy")) -o.rmempty = true -o:value("no", "No") -o:value("unless-stopped", "Unless stopped") -o:value("always", "Always") -o:value("on-failure", "On failure") -o.default = default_config.restart or "unless-stopped" - -local d_network = s:option(ListValue, "network", translate("Networks")) -d_network.rmempty = true -d_network.default = default_config.network or "bridge" - -local d_ip = s:option(Value, "ip", translate("IPv4 Address")) -d_ip.datatype="ip4addr" -d_ip:depends("network", "nil") -d_ip.default = default_config.ip or nil - -o = s:option(DynamicList, "link", translate("Links with other containers")) -o.placeholder = "container_name:alias" -o.rmempty = true -o:depends("network", "bridge") -o.default = default_config.link or nil - -o = s:option(DynamicList, "dns", translate("Set custom DNS servers")) -o.placeholder = "8.8.8.8" -o.rmempty = true -o.default = default_config.dns or nil - -o = s:option(Value, "user", - translate("User(-u)"), - translate("The user that commands are run as inside the container.(format: name|uid[:group|gid])")) -o.placeholder = "1000:1000" -o.rmempty = true -o.default = default_config.user or nil - -o = s:option(DynamicList, "env", - translate("Environmental Variable(-e)"), - translate("Set environment variables to inside the container")) -o.placeholder = "TZ=Asia/Shanghai" -o.rmempty = true -o.default = default_config.env or nil - -o = s:option(DynamicList, "volume", - translate("Bind Mount(-v)"), - translate("Bind mount a volume")) -o.placeholder = "/media:/media:slave" -o.rmempty = true -o.default = default_config.volume or nil - -local d_publish = s:option(DynamicList, "publish", - translate("Exposed Ports(-p)"), - translate("Publish container's port(s) to the host")) -d_publish.placeholder = "2200:22/tcp" -d_publish.rmempty = true -d_publish.default = default_config.publish or nil - -o = s:option(Value, "command", translate("Run command")) -o.placeholder = "/bin/sh init.sh" -o.rmempty = true -o.default = default_config.command or nil - -o = s:option(Flag, "advance", translate("Advance")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.advance or 0 - -o = s:option(Value, "hostname", - translate("Host Name"), - translate("The hostname to use for the container")) -o.rmempty = true -o.default = default_config.hostname or nil -o:depends("advance", 1) - -o = s:option(Flag, "publish_all", - translate("Exposed All Ports(-P)"), - translate("Allocates an ephemeral host port for all of a container's exposed ports")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = default_config.publish_all and 1 or 0 -o:depends("advance", 1) - -o = s:option(DynamicList, "device", - translate("Device(--device)"), - translate("Add host device to the container")) -o.placeholder = "/dev/sda:/dev/xvdc:rwm" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.device or nil - -o = s:option(DynamicList, "tmpfs", - translate("Tmpfs(--tmpfs)"), - translate("Mount tmpfs directory")) -o.placeholder = "/run:rw,noexec,nosuid,size=65536k" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.tmpfs or nil - -o = s:option(DynamicList, "sysctl", - translate("Sysctl(--sysctl)"), - translate("Sysctls (kernel parameters) options")) -o.placeholder = "net.ipv4.ip_forward=1" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.sysctl or nil - -o = s:option(DynamicList, "cap_add", - translate("CAP-ADD(--cap-add)"), - translate("A list of kernel capabilities to add to the container")) -o.placeholder = "NET_ADMIN" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.cap_add or nil - -o = s:option(Value, "cpus", - translate("CPUs"), - translate("Number of CPUs. Number is a fractional number. 0.000 means no limit")) -o.placeholder = "1.5" -o.rmempty = true -o:depends("advance", 1) -o.datatype="ufloat" -o.default = default_config.cpus or nil - -o = 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")) -o.placeholder = "1024" -o.rmempty = true -o:depends("advance", 1) -o.datatype="uinteger" -o.default = default_config.cpu_shares or nil - -o = s:option(Value, "memory", - translate("Memory"), - translate("Memory limit (format: []). Number is a positive integer. Unit can be one of b, k, m, or g. Minimum is 4M")) -o.placeholder = "128m" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.memory or nil - -o = s:option(Value, "blkio_weight", - translate("Block IO Weight"), - translate("Block IO weight (relative weight) accepts a weight value between 10 and 1000")) -o.placeholder = "500" -o.rmempty = true -o:depends("advance", 1) -o.datatype="uinteger" -o.default = default_config.blkio_weight or nil - -o = s:option(Value, "log_driver", - translate("Logging driver"), - translate("The logging driver for the container")) -o.placeholder = "json-file" -o.rmempty = true -o:depends("advance", 1) -o.default = default_config.log_driver or nil - -o = s:option(DynamicList, "log_opt", - translate("Log driver options"), - translate("The logging configuration for this container")) -o.placeholder = "max-size=1m" -o.rmempty = true -o:depends("advance", 1) -o.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 - local ip = v.IPAM and v.IPAM.Config and v.IPAM.Config[1] and v.IPAM.Config[1].Subnet or nil - ipv6 = v.IPAM and v.IPAM.Config and v.IPAM.Config[2] and v.IPAM.Config[2].Subnet or nil - local network_name = v.Name .. " | " .. v.Driver .. (parent and (" | " .. parent) or "") .. (ip and (" | " .. ip) or "").. (ipv6 and (" | " .. ipv6) or "") - d_network:value(v.Name, network_name) - - if v.Name ~= "none" and v.Name ~= "bridge" and v.Name ~= "host" then - d_ip:depends("network", v.Name) - end - - if v.Driver == "bridge" then - d_publish:depends("network", v.Name) - end - end -end - -m.handle = function(self, state, data) - if state ~= FORM_VALID then - return - end - - local tmp - 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 - - if image and not image:match(".-:.+") then - image = image .. ":latest" - end - - local privileged = type(data.privileged) == "number" and (data.privileged == 1 and true or false) or default_config.privileged or false - local restart = data.restart - local env = data.env - local dns = data.dns - local cap_add = data.cap_add - local sysctl = {} - local log_driver = data.log_driver - - tmp = data.sysctl - if type(tmp) == "table" then - for i, v in ipairs(tmp) do - local k,v1 = v:match("(.-)=(.+)") - if k and v1 then - sysctl[k]=v1 - 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 - local memory = data.memory or nil - local cpu_shares = data.cpu_shares or nil - local cpus = data.cpus or nil - local blkio_weight = data.blkio_weight or nil - - local portbindings = {} - local exposedports = {} - - local tmpfs = {} - tmp = data.tmpfs - if type(tmp) == "table" then - for i, v in ipairs(tmp)do - local k= v:match("([^:]+)") - local v1 = v:match(".-:([^:]+)") or "" - if k then - tmpfs[k]=v1 - end - end - end - - local device = {} - tmp = data.device - if type(tmp) == "table" then - for i, v in ipairs(tmp) do - local t = {} - local _,_, h, c, p = v:find("(.-):(.-):(.+)") - if h and c then - t['PathOnHost'] = h - t['PathInContainer'] = c - t['CgroupPermissions'] = p or "rwm" - else - local _,_, h, c = v:find("(.-):(.+)") - if h and c then - t['PathOnHost'] = h - t['PathInContainer'] = c - t['CgroupPermissions'] = "rwm" - else - t['PathOnHost'] = v - t['PathInContainer'] = v - t['CgroupPermissions'] = "rwm" - end - end - - if next(t) ~= nil then - table.insert( device, t ) - end - end - end - - tmp = data.publish or {} - for i, v in ipairs(tmp) do - for v1 ,v2 in string.gmatch(v, "(%d+):([^%s]+)") do - local _,_,p= v2:find("^%d+/(%w+)") - if p == nil then - v2=v2..'/tcp' - end - portbindings[v2] = {{HostPort=v1}} - exposedports[v2] = {HostPort=v1} - end - end - - local link = data.link - tmp = data.command - local command = {} - if tmp ~= nil then - for v in string.gmatch(tmp, "[^%s]+") do - command[#command+1] = v - end - end - - if memory and memory ~= 0 then - _,_,n,unit = memory:find("([%d%.]+)([%l%u]+)") - if n then - unit = unit and unit:sub(1,1):upper() or "B" - if unit == "M" then - memory = tonumber(n) * 1024 * 1024 - elseif unit == "G" then - memory = tonumber(n) * 1024 * 1024 * 1024 - elseif unit == "K" then - memory = tonumber(n) * 1024 - else - memory = tonumber(n) - end - end - end - - create_body.Hostname = network ~= "host" and (hostname or name) or nil - create_body.Tty = tty and true or false - create_body.OpenStdin = interactive and true or false - create_body.User = user - create_body.Cmd = command - create_body.Env = env - create_body.Image = image - create_body.ExposedPorts = exposedports - create_body.HostConfig = create_body.HostConfig or {} - create_body.HostConfig.Dns = dns - create_body.HostConfig.Binds = volume - create_body.HostConfig.RestartPolicy = { Name = restart, MaximumRetryCount = 0 } - create_body.HostConfig.Privileged = privileged and true or false - create_body.HostConfig.PortBindings = portbindings - create_body.HostConfig.Memory = memory and tonumber(memory) - create_body.HostConfig.CpuShares = cpu_shares and tonumber(cpu_shares) - create_body.HostConfig.NanoCPUs = cpus and tonumber(cpus) * 10 ^ 9 - create_body.HostConfig.BlkioWeight = blkio_weight and tonumber(blkio_weight) - create_body.HostConfig.PublishAllPorts = publish_all - - if create_body.HostConfig.NetworkMode ~= network then - create_body.NetworkingConfig = nil - end - - create_body.HostConfig.NetworkMode = network - - if ip then - if create_body.NetworkingConfig and create_body.NetworkingConfig.EndpointsConfig and type(create_body.NetworkingConfig.EndpointsConfig) == "table" then - for k, v in pairs (create_body.NetworkingConfig.EndpointsConfig) do - if k == network and v.IPAMConfig and v.IPAMConfig.IPv4Address then - v.IPAMConfig.IPv4Address = ip - else - create_body.NetworkingConfig.EndpointsConfig = { [network] = { IPAMConfig = { IPv4Address = ip } } } - end - break - end - else - create_body.NetworkingConfig = { EndpointsConfig = { [network] = { IPAMConfig = { IPv4Address = ip } } } } - end - elseif not create_body.NetworkingConfig then - create_body.NetworkingConfig = nil - end - - create_body["HostConfig"]["Tmpfs"] = tmpfs - create_body["HostConfig"]["Devices"] = device - create_body["HostConfig"]["Sysctls"] = sysctl - create_body["HostConfig"]["CapAdd"] = cap_add - create_body["HostConfig"]["LogConfig"] = { - Config = log_opt, - Type = log_driver - } - - if network == "bridge" then - create_body["HostConfig"]["Links"] = link - end - - local pull_image = function(image) - local json_stringify = luci.jsonc and luci.jsonc.stringify - docker:append_status("Images: " .. "pulling" .. " " .. image .. "...\n") - local res = dk.images:create({query = {fromImage=image}}, docker.pull_image_show_status_cb) - if res and res.code and res.code == 200 and (res.body[#res.body] 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 or res.body[#res.body].status == "Status: Image is up to date for ".. image)) then - docker:append_status("done\n") - else - res.code = (res.code == 200) and 500 or res.code - docker:append_status("code:" .. res.code.." ".. (res.body[#res.body] and res.body[#res.body].error or (res.body.message or res.message)).. "\n") - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) - end - end - - docker:clear_status() - local exist_image = false - - if image then - for _, v in ipairs (images) do - if v.RepoTags and v.RepoTags[1] == image then - exist_image = true - break - end - end - if not exist_image then - pull_image(image) - elseif data._force_pull == 1 then - pull_image(image) - end - end - - create_body = docker.clear_empty_tables(create_body) - - docker:append_status("Container: " .. "create" .. " " .. name .. "...") - local res = dk.containers:create({name = name, body = create_body}) - if res and res.code and res.code == 201 then - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/containers")) - else - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message)) - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newcontainer")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua deleted file mode 100755 index c87678b85..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua +++ /dev/null @@ -1,258 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" - -local m, s, o - -local dk = docker.new() -if dk:_ping().code ~= 200 then - lost_state = true -end - -m = SimpleForm("docker", translate("Docker - Network")) -m.redirect = luci.dispatcher.build_url("admin", "docker", "networks") -if lost_state then - m.submit=false - m.reset=false -end - - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(SimpleSection, translate("Create new docker network")) -s.addremove = true -s.anonymous = true - -o = s:option(Value, "name", - translate("Network Name"), - translate("Name of the network that can be selected during container creation")) -o.rmempty = true - -o = s:option(ListValue, "driver", translate("Driver")) -o.rmempty = true -o:value("bridge", translate("Bridge device")) -o:value("macvlan", translate("MAC VLAN")) -o:value("ipvlan", translate("IP VLAN")) -o:value("overlay", translate("Overlay network")) - -o = s:option(Value, "parent", translate("Base device")) -o.rmempty = true -o:depends("driver", "macvlan") -local interfaces = luci.sys and luci.sys.net and luci.sys.net.devices() or {} -for _, v in ipairs(interfaces) do - o:value(v, v) -end -o.default="br-lan" -o.placeholder="br-lan" - -o = s:option(ListValue, "macvlan_mode", translate("Mode")) -o.rmempty = true -o:depends("driver", "macvlan") -o.default="bridge" -o:value("bridge", translate("Bridge (Support direct communication between MAC VLANs)")) -o:value("private", translate("Private (Prevent communication between MAC VLANs)")) -o:value("vepa", translate("VEPA (Virtual Ethernet Port Aggregator)")) -o:value("passthru", translate("Pass-through (Mirror physical device to single MAC VLAN)")) - -o = s:option(ListValue, "ipvlan_mode", translate("Ipvlan Mode")) -o.rmempty = true -o:depends("driver", "ipvlan") -o.default="l3" -o:value("l2", translate("L2 bridge")) -o:value("l3", translate("L3 bridge")) - -o = s:option(Flag, "ingress", - translate("Ingress"), - translate("Ingress network is the network which provides the routing-mesh in swarm mode")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o:depends("driver", "overlay") - -o = s:option(DynamicList, "options", translate("Options")) -o.rmempty = true -o.placeholder="com.docker.network.driver.mtu=1500" - -o = s:option(Flag, "internal", translate("Internal"), translate("Restrict external access to the network")) -o.rmempty = true -o:depends("driver", "overlay") -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -if nixio.fs.access("/etc/config/network") and nixio.fs.access("/etc/config/firewall")then - o = s:option(Flag, "op_macvlan", translate("Create macvlan interface"), translate("Auto create macvlan interface in Openwrt")) - o:depends("driver", "macvlan") - o.disabled = 0 - o.enabled = 1 - o.default = 1 -end - -o = s:option(Value, "subnet", translate("Subnet")) -o.rmempty = true -o.placeholder="10.1.0.0/16" -o.datatype="ip4addr" - -o = s:option(Value, "gateway", translate("Gateway")) -o.rmempty = true -o.placeholder="10.1.1.1" -o.datatype="ip4addr" - -o = s:option(Value, "ip_range", translate("IP range")) -o.rmempty = true -o.placeholder="10.1.1.0/24" -o.datatype="ip4addr" - -o = s:option(DynamicList, "aux_address", translate("Exclude IPs")) -o.rmempty = true -o.placeholder="my-route=10.1.1.1" - -o = s:option(Flag, "ipv6", translate("Enable IPv6")) -o.rmempty = true -o.disabled = 0 -o.enabled = 1 -o.default = 0 - -o = s:option(Value, "subnet6", translate("IPv6 Subnet")) -o.rmempty = true -o.placeholder="fe80::/10" -o.datatype="ip6addr" -o:depends("ipv6", 1) - -o = s:option(Value, "gateway6", translate("IPv6 Gateway")) -o.rmempty = true -o.placeholder="fe80::1" -o.datatype="ip6addr" -o:depends("ipv6", 1) - -m.handle = function(self, state, data) - if state == FORM_VALID then - local name = data.name - local driver = data.driver - - local internal = data.internal == 1 and true or false - - local subnet = data.subnet - local gateway = data.gateway - local ip_range = data.ip_range - - local aux_address = {} - local tmp = data.aux_address or {} - for i,v in ipairs(tmp) do - _,_,k1,v1 = v:find("(.-)=(.+)") - aux_address[k1] = v1 - end - - local options = {} - tmp = data.options or {} - for i,v in ipairs(tmp) do - _,_,k1,v1 = v:find("(.-)=(.+)") - options[k1] = v1 - end - - local ipv6 = data.ipv6 == 1 and true or false - - local create_body = { - Name = name, - Driver = driver, - EnableIPv6 = ipv6, - IPAM = { - Driver= "default" - }, - Internal = internal - } - - if subnet or gateway or ip_range then - create_body["IPAM"]["Config"] = { - { - Subnet = subnet, - Gateway = gateway, - IPRange = ip_range, - AuxAddress = aux_address, - AuxiliaryAddresses = aux_address - } - } - end - - if driver == "macvlan" then - create_body["Options"] = { - macvlan_mode = data.macvlan_mode, - parent = data.parent - } - elseif driver == "ipvlan" then - create_body["Options"] = { - ipvlan_mode = data.ipvlan_mode - } - elseif driver == "overlay" then - create_body["Ingress"] = data.ingerss == 1 and true or false - end - - if ipv6 and data.subnet6 and data.subnet6 then - if type(create_body["IPAM"]["Config"]) ~= "table" then - create_body["IPAM"]["Config"] = {} - end - local index = #create_body["IPAM"]["Config"] - create_body["IPAM"]["Config"][index+1] = { - Subnet = data.subnet6, - Gateway = data.gateway6 - } - end - - if next(options) ~= nil then - create_body["Options"] = create_body["Options"] or {} - for k, v in pairs(options) do - create_body["Options"][k] = v - end - end - - create_body = docker.clear_empty_tables(create_body) - docker:write_status("Network: " .. "create" .. " " .. create_body.Name .. "...") - - local res = dk.networks:create({ - body = create_body - }) - - if res and res.code == 201 then - docker:write_status("Network: " .. "create macvlan interface...") - res = dk.networks:inspect({ - name = create_body.Name - }) - - if driver == "macvlan" and - data.op_macvlan ~= 0 and - res and - res.code and - res.code == 200 and - res.body and - res.body.IPAM and - res.body.IPAM.Config and - res.body.IPAM.Config[1] and - res.body.IPAM.Config[1].Gateway and - res.body.IPAM.Config[1].Subnet then - - docker.create_macvlan_interface(data.name, - data.parent, - res.body.IPAM.Config[1].Gateway, - res.body.IPAM.Config[1].Subnet) - end - - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/networks")) - else - docker:append_status("code:" .. res.code.." ".. (res.body.message and res.body.message or res.message).. "\n") - luci.http.redirect(luci.dispatcher.build_url("admin/docker/newnetwork")) - end - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua deleted file mode 100755 index c91f349ce..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua +++ /dev/null @@ -1,151 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local uci = (require "luci.model.uci").cursor() - -local m, s, o, lost_state -local dk = docker.new() - -if dk:_ping().code ~= 200 then - lost_state = true -end - -m = SimpleForm("dockerd", - translate("Docker - Overview"), - translate("An overview with the relevant data is displayed here with which the LuCI docker client is connected.") -.. - " " .. - [[]] .. - translate("Github") .. - [[]]) -m.submit=false -m.reset=false - -local docker_info_table = {} --- docker_info_table['0OperatingSystem'] = {_key=translate("Operating System"),_value='-'} --- docker_info_table['1Architecture'] = {_key=translate("Architecture"),_value='-'} --- docker_info_table['2KernelVersion'] = {_key=translate("Kernel Version"),_value='-'} -docker_info_table['3ServerVersion'] = {_key=translate("Docker Version"),_value='-'} -docker_info_table['4ApiVersion'] = {_key=translate("Api Version"),_value='-'} -docker_info_table['5NCPU'] = {_key=translate("CPUs"),_value='-'} -docker_info_table['6MemTotal'] = {_key=translate("Total Memory"),_value='-'} -docker_info_table['7DockerRootDir'] = {_key=translate("Docker Root Dir"),_value='-'} -docker_info_table['8IndexServerAddress'] = {_key=translate("Index Server Address"),_value='-'} -docker_info_table['9RegistryMirrors'] = {_key=translate("Registry Mirrors"),_value='-'} - -if nixio.fs.access("/usr/bin/dockerd") and not uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - s = m:section(SimpleSection) - s.template = "dockerman/apply_widget" - s.err=docker:read_status() - s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") - if s.err then - docker:clear_status() - end - s = m:section(Table,{{}}) - s.notitle=true - s.rowcolors=false - s.template = "cbi/nullsection" - - o = s:option(Button, "_start") - o.template = "dockerman/cbi/inlinebutton" - o.inputtitle = lost_state and translate("Start") or translate("Stop") - o.inputstyle = lost_state and "add" or "remove" - o.forcewrite = true - o.write = function(self, section) - docker:clear_status() - - if lost_state then - docker:append_status("Docker daemon: starting") - luci.util.exec("/etc/init.d/dockerd start") - luci.util.exec("sleep 5") - luci.util.exec("/etc/init.d/dockerman start") - - else - docker:append_status("Docker daemon: stopping") - luci.util.exec("/etc/init.d/dockerd stop") - end - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/overview")) - end - - o = s:option(Button, "_restart") - o.template = "dockerman/cbi/inlinebutton" - o.inputtitle = translate("Restart") - o.inputstyle = "reload" - o.forcewrite = true - o.write = function(self, section) - docker:clear_status() - docker:append_status("Docker daemon: restarting") - luci.util.exec("/etc/init.d/dockerd restart") - luci.util.exec("sleep 5") - luci.util.exec("/etc/init.d/dockerman start") - docker:clear_status() - luci.http.redirect(luci.dispatcher.build_url("admin/docker/overview")) - end -end - -s = m:section(Table, docker_info_table) -s:option(DummyValue, "_key", translate("Info")) -s:option(DummyValue, "_value") - -s = m:section(SimpleSection) -s.template = "dockerman/overview" - -s.containers_running = '-' -s.images_used = '-' -s.containers_total = '-' -s.images_total = '-' -s.networks_total = '-' -s.volumes_total = '-' - --- local socket = luci.model.uci.cursor():get("dockerd", "dockerman", "socket_path") -if not lost_state then - local containers_list = dk.containers:list({query = {all=true}}).body - local images_list = dk.images:list().body - local vol = dk.volumes:list() - local volumes_list = vol and vol.body and vol.body.Volumes or {} - local networks_list = dk.networks:list().body or {} - local docker_info = dk:info() - - -- docker_info_table['0OperatingSystem']._value = docker_info.body.OperatingSystem - -- docker_info_table['1Architecture']._value = docker_info.body.Architecture - -- docker_info_table['2KernelVersion']._value = docker_info.body.KernelVersion - docker_info_table['3ServerVersion']._value = docker_info.body.ServerVersion - docker_info_table['4ApiVersion']._value = docker_info.headers["Api-Version"] - docker_info_table['5NCPU']._value = tostring(docker_info.body.NCPU) - docker_info_table['6MemTotal']._value = docker.byte_format(docker_info.body.MemTotal) - if docker_info.body.DockerRootDir then - local statvfs = nixio.fs.statvfs(docker_info.body.DockerRootDir) - local size = statvfs and (statvfs.bavail * statvfs.bsize) or 0 - docker_info_table['7DockerRootDir']._value = docker_info.body.DockerRootDir .. " (" .. tostring(docker.byte_format(size)) .. " " .. translate("Available") .. ")" - end - - docker_info_table['8IndexServerAddress']._value = docker_info.body.IndexServerAddress - for i, v in ipairs(docker_info.body.RegistryConfig.Mirrors) do - docker_info_table['9RegistryMirrors']._value = docker_info_table['9RegistryMirrors']._value == "-" and v or (docker_info_table['9RegistryMirrors']._value .. ", " .. v) - end - - s.images_used = 0 - for i, v in ipairs(images_list) do - for ci,cv in ipairs(containers_list) do - if v.Id == cv.ImageID then - s.images_used = s.images_used + 1 - break - end - end - end - - s.containers_running = tostring(docker_info.body.ContainersRunning) - s.images_used = tostring(s.images_used) - s.containers_total = tostring(docker_info.body.Containers) - s.images_total = tostring(#images_list) - s.networks_total = tostring(#networks_list) - s.volumes_total = tostring(#volumes_list) -else - docker_info_table['3ServerVersion']._value = translate("Can NOT connect to docker daemon, please check!!") -end - -return m diff --git a/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua b/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua deleted file mode 100755 index 43e6bda3a..000000000 --- a/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua +++ /dev/null @@ -1,142 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.model.docker" -local dk = docker.new() - -local m, s, o - -local res, containers, volumes, lost_state - -function get_volumes() - local data = {} - for i, v in ipairs(volumes) do - local index = v.Name - data[index]={} - data[index]["_selected"] = 0 - data[index]["_nameraw"] = v.Name - data[index]["_name"] = v.Name:sub(1,12) - - for ci,cv in ipairs(containers) do - if cv.Mounts and type(cv.Mounts) ~= "table" then - break - end - for vi, vv in ipairs(cv.Mounts) do - if v.Name == vv.Name then - data[index]["_containers"] = (data[index]["_containers"] and (data[index]["_containers"] .. " | ") or "").. - ''.. cv.Names[1]:sub(2)..'' - end - end - end - data[index]["_driver"] = v.Driver - data[index]["_mountpoint"] = nil - - for v1 in v.Mountpoint:gmatch('[^/]+') do - if v1 == index then - data[index]["_mountpoint"] = data[index]["_mountpoint"] .."/" .. v1:sub(1,12) .. "..." - else - data[index]["_mountpoint"] = (data[index]["_mountpoint"] and data[index]["_mountpoint"] or "").."/".. v1 - end - end - data[index]["_created"] = v.CreatedAt - data[index]["_size"] = "-" - end - - return data -end -if dk:_ping().code ~= 200 then - lost_state = true -else - res = dk.volumes:list() - if res and res.code and res.code <300 then - volumes = res.body.Volumes - end - - res = dk.containers:list({ - query = { - all=true - } - }) - if res and res.code and res.code <300 then - containers = res.body - end -end - -local volume_list = not lost_state and get_volumes() or {} - -m = SimpleForm("docker", translate("Docker - Volumes")) -m.submit=false -m.reset=false -m:append(Template("dockerman/volume_size")) - -s = m:section(Table, volume_list, translate("Volumes overview")) - -o = s:option(Flag, "_selected","") -o.disabled = 0 -o.enabled = 1 -o.default = 0 -o.write = function(self, section, value) - volume_list[section]._selected = value -end - -o = s:option(DummyValue, "_name", translate("Name")) -o = s:option(DummyValue, "_driver", translate("Driver")) -o = s:option(DummyValue, "_containers", translate("Containers")) -o.rawhtml = true -o = s:option(DummyValue, "_mountpoint", translate("Mount Point")) -o = s:option(DummyValue, "_size", translate("Size")) -o.rawhtml = true -o = s:option(DummyValue, "_created", translate("Created")) - -s = m:section(SimpleSection) -s.template = "dockerman/apply_widget" -s.err=docker:read_status() -s.err=s.err and s.err:gsub("\n","
"):gsub(" "," ") -if s.err then - docker:clear_status() -end - -s = m:section(Table,{{}}) -s.notitle=true -s.rowcolors=false -s.template="cbi/nullsection" - -o = s:option(Button, "remove") -o.inputtitle= translate("Remove") -o.template = "dockerman/cbi/inlinebutton" -o.inputstyle = "remove" -o.forcewrite = true -o.disable = lost_state -o.write = function(self, section) - local volume_selected = {} - - for k in pairs(volume_list) do - if volume_list[k]._selected == 1 then - volume_selected[#volume_selected+1] = k - end - end - - if next(volume_selected) ~= nil then - local success = true - docker:clear_status() - for _,vol in ipairs(volume_selected) do - docker:append_status("Volumes: " .. "remove" .. " " .. vol .. "...") - local msg = dk.volumes["remove"](dk, {id = vol}) - if msg and msg.code and msg.code ~= 204 then - docker:append_status("code:" .. msg.code.." ".. (msg.body.message and msg.body.message or msg.message).. "\n") - success = false - else - docker:append_status("done\n") - end - end - - if success then - docker:clear_status() - end - luci.http.redirect(luci.dispatcher.build_url("admin/docker/volumes")) - end -end - -return m diff --git a/luci-app-dockerman/luasrc/model/docker.lua b/luci-app-dockerman/luasrc/model/docker.lua deleted file mode 100755 index 2a902912a..000000000 --- a/luci-app-dockerman/luasrc/model/docker.lua +++ /dev/null @@ -1,507 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface -Copyright 2019 lisaac -]]-- - -local docker = require "luci.docker" -local fs = require "nixio.fs" -local uci = (require "luci.model.uci").cursor() - -local _docker = {} -_docker.options = {} - ---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 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 -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 -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 - 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) - if t[k] and next(t[k]) == nil then - t[k] = nil - end - end - end - end - - return t -end - -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) - - 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() - - 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 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 - - 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 - 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 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 and res.code and res.code > 300 then - return res - end - _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 - -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) -end - -_docker.new = function() - local host = nil - local port = nil - local socket_path = nil - local debug_path = nil - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") then - host = uci:get("dockerd", "dockerman", "remote_host") or nil - port = uci:get("dockerd", "dockerman", "remote_port") or nil - else - socket_path = uci:get("dockerd", "dockerman", "socket_path") or "/var/run/docker.sock" - end - - local debug = uci:get_bool("dockerd", "dockerman", "debug") - if debug then - debug_path = uci:get("dockerd", "dockerman", "debug_path") or "/tmp/.docker_debug" - end - - local status_path = uci:get("dockerd", "dockerman", "status_path") or "/tmp/.docker_action_status" - - _docker.options = { - host = host, - port = port, - socket_path = socket_path, - debug = debug, - debug_path = debug_path, - status_path = status_path - } - - local _new = docker.new(_docker.options) - _new.containers_upgrade = upgrade - _new.containers_duplicate_config = duplicate_config - - return _new -end - -_docker.options.status_path = uci:get("dockerd", "dockerman", "status_path") or "/tmp/.docker_action_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() -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() -end - -_docker.read_status=function(self) - return fs.readfile(self.options.status_path) -end - -_docker.clear_status=function(self) - 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 -end - ---{"status":"Pulling from library\/debian","id":"latest"} ---{"status":"Pulling fs layer","progressDetail":[],"id":"50e431f79093"} ---{"status":"Downloading","progressDetail":{"total":50381971,"current":2029978},"id":"50e431f79093","progress":"[==> ] 2.03MB\/50.38MB"} ---{"status":"Download complete","progressDetail":[],"id":"50e431f79093"} ---{"status":"Extracting","progressDetail":{"total":50381971,"current":17301504},"id":"50e431f79093","progress":"[=================> ] 17.3MB\/50.38MB"} ---{"status":"Pull complete","progressDetail":[],"id":"50e431f79093"} ---{"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) -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) -end - -_docker.create_macvlan_interface = function(name, device, gateway, subnet) - if not fs.access("/etc/config/network") or not fs.access("/etc/config/firewall") then - return - end - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") 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 fs.access("/etc/config/network") or not fs.access("/etc/config/firewall") then - return - end - - if uci:get_bool("dockerd", "dockerman", "remote_endpoint") 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 - -_docker.byte_format = function (byte) - if not byte then return 'NaN' end - local suff = {"B", "KB", "MB", "GB", "TB"} - for i=1, 5 do - if byte > 1024 and i < 5 then - byte = byte / 1024 - else - return string.format("%.2f %s", byte, suff[i]) - end - end -end - -return _docker diff --git a/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm b/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm deleted file mode 100755 index f96b2d72a..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm +++ /dev/null @@ -1,147 +0,0 @@ - - - diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm deleted file mode 100755 index a061a6dba..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinebutton.htm +++ /dev/null @@ -1,7 +0,0 @@ -
- <% if self:cfgvalue(section) ~= false then %> - " type="submit"" <% if self.disable then %>disabled <% end %><%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> - <% else %> - - - <% end %> -
diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm deleted file mode 100755 index e4b0cf7a0..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm +++ /dev/null @@ -1,33 +0,0 @@ -
- - <%- if self.password then -%> - /> - <%- end -%> - 0, "data-choices", { self.keylist, self.vallist }) - %> /> - <%- if self.password then -%> -
- <% end %> -
diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm deleted file mode 100755 index 244d2c10a..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/namedsection.htm +++ /dev/null @@ -1,9 +0,0 @@ -<% if self:cfgvalue(self.section) then section = self.section %> -
- <%+cbi/tabmenu%> -
- <%+cbi/ucisection%> -
-
-<% end %> - diff --git a/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm b/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm deleted file mode 100755 index 04f7bc2ee..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/cbi/xfvalue.htm +++ /dev/null @@ -1,10 +0,0 @@ -<%+cbi/valueheader%> - /> - disabled <% end %><%= - attr("id", cbid) .. attr("name", cbid) .. attr("value", self.enabled or 1) .. - ifattr((self:cfgvalue(section) or self.default) == self.enabled, "checked", "checked") - %> /> - > -<%+cbi/valuefooter%> diff --git a/luci-app-dockerman/luasrc/view/dockerman/container.htm b/luci-app-dockerman/luasrc/view/dockerman/container.htm deleted file mode 100755 index 9f05d9d58..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container.htm +++ /dev/null @@ -1,28 +0,0 @@ -
- - - diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_console.htm b/luci-app-dockerman/luasrc/view/dockerman/container_console.htm deleted file mode 100755 index 1a4dc2a6b..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_console.htm +++ /dev/null @@ -1,6 +0,0 @@ -
- -
- diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm b/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm deleted file mode 100755 index 2e0650d9d..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm +++ /dev/null @@ -1,332 +0,0 @@ - -
- -
- - -
-
-
- - diff --git a/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm b/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm deleted file mode 100755 index bbcd633e7..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm +++ /dev/null @@ -1,81 +0,0 @@ - diff --git a/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm b/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm deleted file mode 100755 index d88e28be9..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/containers_running_stats.htm +++ /dev/null @@ -1,91 +0,0 @@ - \ No newline at end of file diff --git a/luci-app-dockerman/luasrc/view/dockerman/images_import.htm b/luci-app-dockerman/luasrc/view/dockerman/images_import.htm deleted file mode 100755 index 0ad6e0fce..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/images_import.htm +++ /dev/null @@ -1,104 +0,0 @@ - - -
- disabled <% end %>/> - -
- - diff --git a/luci-app-dockerman/luasrc/view/dockerman/images_load.htm b/luci-app-dockerman/luasrc/view/dockerman/images_load.htm deleted file mode 100755 index b201510ac..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/images_load.htm +++ /dev/null @@ -1,40 +0,0 @@ -
- disabled <% end %>/> - -
- diff --git a/luci-app-dockerman/luasrc/view/dockerman/logs.htm b/luci-app-dockerman/luasrc/view/dockerman/logs.htm deleted file mode 100755 index 6cd2cb095..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/logs.htm +++ /dev/null @@ -1,13 +0,0 @@ -<% if self.title == "Events" then %> -<%+header%> -

<%:Docker - Events%>

-
-

<%:Events%>

-<% end %> -
- -
-<% if self.title == "Events" then %> -
-<%+footer%> -<% end %> diff --git a/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm b/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm deleted file mode 100755 index 338fd59d5..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm +++ /dev/null @@ -1,102 +0,0 @@ - - - -<%+cbi/valueheader%> - - - -<%+cbi/valuefooter%> diff --git a/luci-app-dockerman/luasrc/view/dockerman/overview.htm b/luci-app-dockerman/luasrc/view/dockerman/overview.htm deleted file mode 100755 index e491fc512..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/overview.htm +++ /dev/null @@ -1,197 +0,0 @@ - - -
-
-
-
-
- -
-
-
-

<%:Containers%>

-

- <%- if self.containers_total ~= "-" then -%><%- end -%> - <%=self.containers_running%> - /<%=self.containers_total%> - <%- if self.containers_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Images%>

-

- <%- if self.images_total ~= "-" then -%><%- end -%> - <%=self.images_used%> - /<%=self.images_total%> - <%- if self.images_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Networks%>

-

- <%- if self.networks_total ~= "-" then -%><%- end -%> - <%=self.networks_total%> - - <%- if self.networks_total ~= "-" then -%><%- end -%> -

-
-
-
-
-
-
-
- -
-
-
-

<%:Volumes%>

-

- <%- if self.volumes_total ~= "-" then -%><%- end -%> - <%=self.volumes_total%> - - <%- if self.volumes_total ~= "-" then -%><%- end -%> -

-
-
-
-
diff --git a/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm b/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm deleted file mode 100755 index dc024734b..000000000 --- a/luci-app-dockerman/luasrc/view/dockerman/volume_size.htm +++ /dev/null @@ -1,21 +0,0 @@ - \ No newline at end of file diff --git a/luci-app-dockerman/po/templates/dockerman.pot b/luci-app-dockerman/po/templates/dockerman.pot deleted file mode 100755 index 0d6a5de98..000000000 --- a/luci-app-dockerman/po/templates/dockerman.pot +++ /dev/null @@ -1,1002 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:619 -msgid "A list of kernel capabilities to add to the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:69 -msgid "Access Control" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:223 -msgid "Add" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:595 -msgid "Add host device to the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:571 -msgid "Advance" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:586 -msgid "Allocates an ephemeral host port for all of a container's exposed ports" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "Allowed access interfaces" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:498 -msgid "Always pull image first" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:29 -msgid "" -"An overview with the relevant data is displayed here with which the LuCI " -"docker client is connected." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:43 -msgid "Api Version" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Auto create macvlan interface in Openwrt" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:18 -msgid "Auto start" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:134 -msgid "Available" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:47 -msgid "Base device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:553 -msgid "Bind Mount(-v)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:554 -msgid "Bind mount a volume" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:596 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:652 -msgid "Block IO Weight" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:653 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:597 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:61 -msgid "Bridge (Support direct communication between MAC VLANs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:42 -msgid "Bridge device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:84 -msgid "" -"By entering a valid image name with the corresponding version, the docker " -"image can be downloaded from the configured registry." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:618 -msgid "CAP-ADD(--cap-add)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:581 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:635 -msgid "CPU Shares Weight" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:779 -msgid "CPU Useage" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:636 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:582 -msgid "" -"CPU shares relative weight, if 0 is set, the system will ignore the value " -"and use the default of 1024." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:573 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:626 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:44 -msgid "CPUs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:159 -msgid "Can NOT connect to docker daemon, please check!!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Cancel" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:60 -msgid "Client connection" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:347 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:687 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:182 -msgid "Command" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:100 -msgid "Command line" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:72 -msgid "Command line Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:17 -msgid "Configuration" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:36 -msgid "Configure the default bridge network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:405 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:707 -msgid "Connect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:403 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:437 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:473 -msgid "Connect Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:74 -msgid "Connect to remote docker endpoint" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:7 -msgid "Console" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:161 -msgid "Container Info" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:650 -msgid "Container Inspect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:671 -msgid "Container Logs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:473 -msgid "Container Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:92 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:58 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:29 -msgid "Container detail" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:38 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:148 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:87 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:133 -msgid "Containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Create macvlan interface" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:465 -msgid "Create new docker container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:31 -msgid "Create new docker network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:312 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:153 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:92 -msgid "Created" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "DELETING" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:371 -msgid "DNS" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:51 -msgid "Debug" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:35 -msgid "Default bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:363 -msgid "Device" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:594 -msgid "Device(--device)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:396 -msgid "Disconnect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:14 -msgid "Docker" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:12 -msgid "Docker - Configuration" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:192 -msgid "Docker - Container (%s)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:128 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:450 -msgid "Docker - Containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:3 -msgid "Docker - Events" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:72 -msgid "Docker - Images" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:15 -msgid "Docker - Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:54 -msgid "Docker - Networks" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:28 -msgid "Docker - Overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:69 -msgid "Docker - Volumes" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:16 -msgid "Docker Daemon settings" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:489 -msgid "Docker Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:30 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:46 -msgid "Docker Root Dir" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:93 -msgid "Docker Socket Path" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:42 -msgid "Docker Version" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm:91 -msgid "Docker actions done." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:70 -msgid "DockerMan" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:13 -msgid "DockerMan is a simple docker manager client for LuCI" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:68 -msgid "DockerMan settings" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:172 -msgid "Download" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:82 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:85 -msgid "Driver" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:265 -msgid "Duplicate/Edit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:120 -msgid "Enable IPv6" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:351 -msgid "Env" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:546 -msgid "Environmental Variable(-e)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:54 -msgid "Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:42 -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:5 -msgid "Events" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:116 -msgid "Exclude IPs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:247 -msgid "Export" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:585 -msgid "Exposed All Ports(-P)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:560 -msgid "Exposed Ports(-p)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:55 -msgid "Fatal" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:6 -msgid "File" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:324 -msgid "Finish Time" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:220 -msgid "Force Remove" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:88 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:106 -msgid "Gateway" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:33 -msgid "Github" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:4 -msgid "Go to relevant configuration page" -msgstr "" - -#: applications/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json:3 -msgid "Grant UCI access for luci-app-dockerman" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:330 -msgid "Healthy" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:578 -msgid "Host Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:100 -msgid "Host or IP Address for the connection to a remote docker instance" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:300 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:78 -msgid "ID" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:44 -msgid "IP VLAN" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:111 -msgid "IP range" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:522 -msgid "IPv4 Address" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:132 -msgid "IPv6 Gateway" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:126 -msgid "IPv6 Subnet" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:304 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:151 -msgid "Images" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:132 -msgid "Images overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:4 -msgid "Import" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:125 -msgid "Import Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:47 -msgid "Index Server Address" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:52 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:414 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:102 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:3 -msgid "Info" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:74 -msgid "Ingress" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:75 -msgid "" -"Ingress network is the network which provides the routing-mesh in swarm mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:8 -msgid "Inspect" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:477 -msgid "Interactive (-i)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Internal" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:66 -msgid "Ipvlan Mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:43 -msgid "" -"It replaces the daemon registry mirrors with a new set of registry mirrors" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:238 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:264 -msgid "Kill" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:70 -msgid "L2 bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:71 -msgid "L3 bridge" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:359 -msgid "Links" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:527 -msgid "Links with other containers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:283 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_load.htm:2 -msgid "Load" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:49 -msgid "Log Level" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:661 -msgid "Log driver options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:9 -msgid "Logs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:43 -msgid "MAC VLAN" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:589 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:644 -msgid "Memory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:783 -msgid "Memory Useage" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:645 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:590 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:57 -msgid "Mode" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:90 -msgid "Mount Point" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:603 -msgid "Mount tmpfs directory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:343 -msgid "Mount/Volume" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:175 -msgid "Mounts" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:295 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:419 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:83 -msgid "Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:37 -msgid "Name of the network that can be selected during container creation" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:394 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:528 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:169 -msgid "Network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:80 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:36 -msgid "Network Name" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:518 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:169 -msgid "Networks" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:59 -msgid "Networks overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:104 -msgid "New" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "New tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:627 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:574 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:73 -msgid "" -"On this page all images are displayed that are available on the system and " -"with which a container can be created." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:193 -msgid "On this page, the selected container can be managed." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:82 -msgid "Options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:45 -msgid "Overlay network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:37 -msgid "Overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "PLEASE CONFIRM" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:84 -msgid "Parent Interface" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:64 -msgid "Pass-through (Mirror physical device to single MAC VLAN)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Please input new tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:270 -msgid "Please input the PATH and select the file !" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:82 -msgid "Please input the PORT or HOST IP of remote docker instance!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:86 -msgid "Please input the SOCKET PATH of docker daemon!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Plese input command line:" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:355 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:172 -msgid "Ports" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "Ports allowed to be accessed" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:62 -msgid "Private (Prevent communication between MAC VLANs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:504 -msgid "Privileged" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:561 -msgid "Publish container's port(s) to the host" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:100 -msgid "Pull" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:83 -msgid "Pull Image" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:42 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:48 -msgid "Registry Mirrors" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:73 -msgid "Remote Endpoint" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:99 -msgid "Remote Host" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:106 -msgid "Remote Port" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:210 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:115 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:108 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:173 -msgid "Remove" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:43 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:82 -msgid "Remove tag" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:171 -msgid "Rename" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:145 -msgid "RepoTags" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:469 -msgid "Resolve CLI" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:4 -msgid "Resources" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:220 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:244 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:87 -msgid "Restart" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:334 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:427 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:510 -msgid "Restart Policy" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Restrict external access to the network" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:31 -msgid "Reveal/hide password" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:566 -msgid "Run command" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:230 -msgid "Save" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:533 -msgid "Set custom DNS servers" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:547 -msgid "Set environment variables to inside the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:50 -msgid "Set the logging level" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:151 -msgid "Size" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:61 -msgid "" -"Specifies where the Docker daemon will listen for client connections " -"(default: unix:///var/run/docker.sock)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:211 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:234 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Start" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:319 -msgid "Start Time" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:789 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:790 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:5 -msgid "Stats" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:308 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:165 -msgid "Status" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:229 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:254 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Stop" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Submit" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:86 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:101 -msgid "Subnet" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:375 -msgid "Sysctl" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:610 -msgid "Sysctl(--sysctl)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:611 -msgid "Sysctls (kernel parameters) options" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:792 -msgid "TOP" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:483 -msgid "TTY (-t)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:56 -msgid "TX/RX" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:579 -msgid "The hostname to use for the container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:662 -msgid "The logging configuration for this container" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:540 -msgid "" -"The user that commands are run as inside the container.(format: name|uid[:" -"group|gid])" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:129 -msgid "" -"This page displays all containers that have been created on the connected " -"docker host." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:55 -msgid "" -"This page displays all docker networks that have been created on the " -"connected docker host." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:367 -msgid "Tmpfs" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:602 -msgid "Tmpfs(--tmpfs)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:45 -msgid "Total Memory" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:697 -msgid "UID" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:297 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:336 -msgid "Update" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:256 -msgid "Upgrade" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:7 -msgid "Upload" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:303 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:304 -msgid "Upload Error" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:294 -msgid "Upload Success" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:48 -msgid "Upload/Download" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:339 -msgid "User" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:539 -msgid "User(-u)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:63 -msgid "VEPA (Virtual Ethernet Port Aggregator)" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:41 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:187 -msgid "Volumes" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:73 -msgid "Volumes overview" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:53 -msgid "Warning" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:126 -msgid "" -"When pressing the Import button, both a local image can be loaded onto the " -"system and a valid image tar can be downloaded from remote." -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "" -"Which Port(s) can be accessed, it's not restricted by the Allowed Access " -"interfaces configuration. Use this configuration with caution!" -msgstr "" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "" -"Which interface(s) can access containers under the bridge network, fill-in " -"Interface Name" -msgstr "" diff --git a/luci-app-dockerman/po/zh-cn/dockerman.po b/luci-app-dockerman/po/zh-cn/dockerman.po deleted file mode 100755 index 2bdc11b8d..000000000 --- a/luci-app-dockerman/po/zh-cn/dockerman.po +++ /dev/null @@ -1,1094 +0,0 @@ -msgid "" -msgstr "" -"PO-Revision-Date: 2021-03-19 04:16+0000\n" -"Last-Translator: Eric \n" -"Language-Team: Chinese (Simplified) \n" -"Language: zh_Hans\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.5.2-dev\n" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:619 -msgid "A list of kernel capabilities to add to the container" -msgstr "要添加到容器的内核功能列表" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:69 -msgid "Access Control" -msgstr "访问控制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:223 -msgid "Add" -msgstr "新增" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:595 -msgid "Add host device to the container" -msgstr "将主机设备添加到容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:571 -msgid "Advance" -msgstr "高级选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:586 -msgid "Allocates an ephemeral host port for all of a container's exposed ports" -msgstr "为容器的所有暴露端口分配临时主机端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "Allowed access interfaces" -msgstr "允许的访问接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:498 -msgid "Always pull image first" -msgstr "总是先拉取镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:29 -msgid "" -"An overview with the relevant data is displayed here with which the LuCI " -"docker client is connected." -msgstr "在此展示与LuCI docker客户端相连接的相关数据的概览。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:43 -msgid "Api Version" -msgstr "Api 版本" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Auto create macvlan interface in Openwrt" -msgstr "在 Openwrt 中自动创建 macvlan 界面" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:18 -msgid "Auto start" -msgstr "自动启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:134 -msgid "Available" -msgstr "可用" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:47 -msgid "Base device" -msgstr "基设备" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:553 -msgid "Bind Mount(-v)" -msgstr "绑定挂载(-v)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:554 -msgid "Bind mount a volume" -msgstr "绑定挂载卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:596 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:652 -msgid "Block IO Weight" -msgstr "块 IO 权重" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:653 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000" -msgstr "块 IO 权重(相对权重)接受10到1000之间的数值" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:597 -msgid "" -"Block IO weight (relative weight) accepts a weight value between 10 and 1000." -msgstr "块 IO 权重(相对权重)接受10到1000之间的数值。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:61 -msgid "Bridge (Support direct communication between MAC VLANs)" -msgstr "桥接(支持 MAC VLAN 之间的直接通信)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:42 -msgid "Bridge device" -msgstr "Bridge device" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:84 -msgid "" -"By entering a valid image name with the corresponding version, the docker " -"image can be downloaded from the configured registry." -msgstr "" -"通过输入具有相应版本的有效映像名称,可以从镜像存储中心(Registry)中下载" -"docker映像。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:618 -msgid "CAP-ADD(--cap-add)" -msgstr "权限控制(--cap-add)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:581 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:635 -msgid "CPU Shares Weight" -msgstr "CPU 共享权重" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:779 -msgid "CPU Useage" -msgstr "CPU 使用率" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:636 -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" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:582 -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。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:573 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:626 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:44 -msgid "CPUs" -msgstr "线程数量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:159 -msgid "Can NOT connect to docker daemon, please check!!" -msgstr "无法连接到docker守护进程(docker daemon),请检查!!" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Cancel" -msgstr "取消" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:60 -msgid "Client connection" -msgstr "客户端连接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:347 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:687 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:182 -msgid "Command" -msgstr "命令" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:100 -msgid "Command line" -msgstr "命令行" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:72 -msgid "Command line Error" -msgstr "命令行错误" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:17 -msgid "Configuration" -msgstr "配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:36 -msgid "Configure the default bridge network" -msgstr "配置默认桥接网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:405 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:707 -msgid "Connect" -msgstr "连接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:403 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:437 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:473 -msgid "Connect Network" -msgstr "连接网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:74 -msgid "Connect to remote docker endpoint" -msgstr "连接到远程docker" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:7 -msgid "Console" -msgstr "控制台" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:161 -msgid "Container Info" -msgstr "容器信息" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:650 -msgid "Container Inspect" -msgstr "检查容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:671 -msgid "Container Logs" -msgstr "容器日志" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:473 -msgid "Container Name" -msgstr "容器名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:92 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:58 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:29 -msgid "Container detail" -msgstr "容器详情" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:38 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:148 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:87 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:133 -msgid "Containers" -msgstr "容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:94 -msgid "Create macvlan interface" -msgstr "创建 macvlan 接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:465 -msgid "Create new docker container" -msgstr "创建 docker 容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:31 -msgid "Create new docker network" -msgstr "创建 docker 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:312 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:153 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:92 -msgid "Created" -msgstr "创建时间" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "DELETING" -msgstr "删除中" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:371 -msgid "DNS" -msgstr "DNS" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:51 -msgid "Debug" -msgstr "调试" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:35 -msgid "Default bridge" -msgstr "默认桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:363 -msgid "Device" -msgstr "设备" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:594 -msgid "Device(--device)" -msgstr "设备(--device)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:396 -msgid "Disconnect" -msgstr "断开" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:14 -msgid "Docker" -msgstr "Docker" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:12 -msgid "Docker - Configuration" -msgstr "Docker - 配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:192 -msgid "Docker - Container (%s)" -msgstr "Docker - 容器 (%s)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:128 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:450 -msgid "Docker - Containers" -msgstr "Docker - 容器" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:3 -msgid "Docker - Events" -msgstr "Docker - 事件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:72 -msgid "Docker - Images" -msgstr "Docker - 镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:15 -msgid "Docker - Network" -msgstr "Docker - 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:54 -msgid "Docker - Networks" -msgstr "Docker - 网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:28 -msgid "Docker - Overview" -msgstr "Docker - 概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:69 -msgid "Docker - Volumes" -msgstr "Docker - 存储卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:16 -msgid "Docker Daemon settings" -msgstr "Docker 服务端(Docker Daemon)设置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:489 -msgid "Docker Image" -msgstr "Docker 镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:30 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:46 -msgid "Docker Root Dir" -msgstr "Docker 根目录" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:93 -msgid "Docker Socket Path" -msgstr "Docker 套接字路径" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:42 -msgid "Docker Version" -msgstr "Docker 版本" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/apply_widget.htm:91 -msgid "Docker actions done." -msgstr "Docker 执行完成。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:70 -msgid "DockerMan" -msgstr "DockerMan" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:13 -msgid "DockerMan is a simple docker manager client for LuCI" -msgstr "DockerMan是用于LuCI的简单docker管理器客户端" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:68 -msgid "DockerMan settings" -msgstr "DockerMan设置" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:172 -msgid "Download" -msgstr "下载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:82 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:85 -msgid "Driver" -msgstr "驱动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:265 -msgid "Duplicate/Edit" -msgstr "复制/编辑" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:120 -msgid "Enable IPv6" -msgstr "启用 IPv6" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:351 -msgid "Env" -msgstr "环境变量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:546 -msgid "Environmental Variable(-e)" -msgstr "环境变量(-e)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:54 -msgid "Error" -msgstr "错误" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:42 -#: applications/luci-app-dockerman/luasrc/view/dockerman/logs.htm:5 -msgid "Events" -msgstr "事件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:116 -msgid "Exclude IPs" -msgstr "排除 IP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:247 -msgid "Export" -msgstr "导出" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:585 -msgid "Exposed All Ports(-P)" -msgstr "暴露所有端口(-P)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:560 -msgid "Exposed Ports(-p)" -msgstr "暴露端口(-p)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:55 -msgid "Fatal" -msgstr "致命的" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:6 -msgid "File" -msgstr "文件" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:324 -msgid "Finish Time" -msgstr "完成时间" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:220 -msgid "Force Remove" -msgstr "强制移除" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:88 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:106 -msgid "Gateway" -msgstr "网关" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:33 -msgid "Github" -msgstr "Github" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:4 -msgid "Go to relevant configuration page" -msgstr "进入相关配置页面" - -#: applications/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json:3 -msgid "Grant UCI access for luci-app-dockerman" -msgstr "授予 UCI 访问 luci-app-dockerman 的权限" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:330 -msgid "Healthy" -msgstr "健康" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:578 -msgid "Host Name" -msgstr "主机名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:100 -msgid "Host or IP Address for the connection to a remote docker instance" -msgstr "连接到远程Docker实例的主机名或IP地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:300 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:142 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:78 -msgid "ID" -msgstr "ID" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:44 -msgid "IP VLAN" -msgstr "IP VLAN" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:111 -msgid "IP range" -msgstr "IP 范围" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:522 -msgid "IPv4 Address" -msgstr "IPv4 地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:132 -msgid "IPv6 Gateway" -msgstr "IPv6 网关" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:126 -msgid "IPv6 Subnet" -msgstr "IPv6 子网" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:304 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Image" -msgstr "镜像" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:151 -msgid "Images" -msgstr "镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:132 -msgid "Images overview" -msgstr "镜像概览" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:4 -msgid "Import" -msgstr "导入" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:125 -msgid "Import Image" -msgstr "导入镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:47 -msgid "Index Server Address" -msgstr "索引服务器地址" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:52 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:414 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:102 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:3 -msgid "Info" -msgstr "信息" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:74 -msgid "Ingress" -msgstr "入口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:75 -msgid "" -"Ingress network is the network which provides the routing-mesh in swarm mode" -msgstr "入口网络是以群模式提供路由网格的网络" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:8 -msgid "Inspect" -msgstr "检查" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:477 -msgid "Interactive (-i)" -msgstr "交互(-i)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Internal" -msgstr "内部" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:66 -msgid "Ipvlan Mode" -msgstr "Ipvlan 模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:43 -msgid "" -"It replaces the daemon registry mirrors with a new set of registry mirrors" -msgstr "" -"设置新的镜像存储中心(Registry)镜像源,这将取代服务端(daemon)配置的镜像存" -"储中心(Registry)的镜像源" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:238 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:264 -msgid "Kill" -msgstr "强制关闭" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:70 -msgid "L2 bridge" -msgstr "L2 桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:71 -msgid "L3 bridge" -msgstr "L3 桥接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:359 -msgid "Links" -msgstr "链接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:527 -msgid "Links with other containers" -msgstr "与其他容器的链接" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:283 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_load.htm:2 -msgid "Load" -msgstr "负载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:49 -msgid "Log Level" -msgstr "日志等级" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:661 -msgid "Log driver options" -msgstr "日志驱动选项" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:9 -msgid "Logs" -msgstr "日志" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:43 -msgid "MAC VLAN" -msgstr "MAC VLAN" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:589 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:644 -msgid "Memory" -msgstr "内存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:783 -msgid "Memory Useage" -msgstr "内存使用率" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:645 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M" -msgstr "" -"内存限制(格式:<数字>[<单位>])。数字是正整数。单位可以是 b、k、m 或 g 之一。" -"最小值为 4M" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:590 -msgid "" -"Memory limit (format: []). Number is a positive integer. Unit " -"can be one of b, k, m, or g. Minimum is 4M." -msgstr "" -"内存限制(格式:<数字>[<单位>])。数字是正整数。单位可以是 b、k、m 或 g 之一。" -"最小值为 4M。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:57 -msgid "Mode" -msgstr "模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:90 -msgid "Mount Point" -msgstr "挂载点" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:603 -msgid "Mount tmpfs directory" -msgstr "挂载 tmpfs 目录" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:343 -msgid "Mount/Volume" -msgstr "挂载/卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:175 -msgid "Mounts" -msgstr "挂载点" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:295 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:419 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:83 -msgid "Name" -msgstr "名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:37 -msgid "Name of the network that can be selected during container creation" -msgstr "在容器创建时可以选择网络的名称" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:394 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:528 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:169 -msgid "Network" -msgstr "网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:80 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:36 -msgid "Network Name" -msgstr "网络名称" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:40 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:518 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:169 -msgid "Networks" -msgstr "网络" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:59 -msgid "Networks overview" -msgstr "网络概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:104 -msgid "New" -msgstr "新建" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:39 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "New tag" -msgstr "新建标签" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:627 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit" -msgstr "CPU 数量。数字是小数。0.000 表示没有限制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:574 -msgid "Number of CPUs. Number is a fractional number. 0.000 means no limit." -msgstr "CPU 数量。数字是小数。0.000 表示没有限制。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:73 -msgid "" -"On this page all images are displayed that are available on the system and " -"with which a container can be created." -msgstr "在此页面上,显示系统上可用的所有镜像文件,并可以用它们来创建容器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:193 -msgid "On this page, the selected container can be managed." -msgstr "在此页面可以管理所选的容器。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:82 -msgid "Options" -msgstr "选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:45 -msgid "Overlay network" -msgstr "Overlay network" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:37 -msgid "Overview" -msgstr "概览" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:33 -msgid "PLEASE CONFIRM" -msgstr "请确认" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:84 -msgid "Parent Interface" -msgstr "父接口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:64 -msgid "Pass-through (Mirror physical device to single MAC VLAN)" -msgstr "直通(将物理设备镜像到单独的 MAC VLAN)" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:54 -msgid "Please input new tag" -msgstr "请输入新的标签" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:270 -msgid "Please input the PATH and select the file !" -msgstr "请输入路径并选择文件!" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:82 -msgid "Please input the PORT or HOST IP of remote docker instance!" -msgstr "请输入合法的远程docker实例端口和主机IP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:86 -msgid "Please input the SOCKET PATH of docker daemon!" -msgstr "请输入合法docker服务端(docker daemon)的SOCKET地址" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Plese input command line:" -msgstr "请输入 的命令行:" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:355 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:172 -msgid "Ports" -msgstr "端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "Ports allowed to be accessed" -msgstr "允许访问的端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:62 -msgid "Private (Prevent communication between MAC VLANs)" -msgstr "专用(阻止 MAC VLAN 之间的通信)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:504 -msgid "Privileged" -msgstr "特权模式" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:561 -msgid "Publish container's port(s) to the host" -msgstr "将容器的端口发布到主机" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:100 -msgid "Pull" -msgstr "拉取" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:83 -msgid "Pull Image" -msgstr "拉取镜像" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:42 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:48 -msgid "Registry Mirrors" -msgstr "镜像加速器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:73 -msgid "Remote Endpoint" -msgstr "远程实例" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:99 -msgid "Remote Host" -msgstr "远程主机" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:106 -msgid "Remote Port" -msgstr "远程端口" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:274 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:210 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:115 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:108 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:173 -msgid "Remove" -msgstr "移除" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:43 -#: applications/luci-app-dockerman/luasrc/view/dockerman/images_import.htm:82 -msgid "Remove tag" -msgstr "移除标签" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:171 -msgid "Rename" -msgstr "重命名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:145 -msgid "RepoTags" -msgstr "仓库标签" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:469 -msgid "Resolve CLI" -msgstr "解析 CLI" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:4 -msgid "Resources" -msgstr "资源" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:220 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:244 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:87 -msgid "Restart" -msgstr "重新启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:334 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:427 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:510 -msgid "Restart Policy" -msgstr "重启策略" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:86 -msgid "Restrict external access to the network" -msgstr "限制外部网络访问" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/cbi/inlinevalue.htm:31 -msgid "Reveal/hide password" -msgstr "显示/隐藏 密码" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:566 -msgid "Run command" -msgstr "运行命令" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:230 -msgid "Save" -msgstr "保存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:533 -msgid "Set custom DNS servers" -msgstr "设置自定义 DNS 服务器" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:547 -msgid "Set environment variables to inside the container" -msgstr "在容器内部设置环境变量" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:50 -msgid "Set the logging level" -msgstr "设置日志记录级别" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:151 -msgid "Size" -msgstr "大小" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:61 -msgid "" -"Specifies where the Docker daemon will listen for client connections " -"(default: unix:///var/run/docker.sock)" -msgstr "" -"指定Docker服务端(Docker daemon)将在何处侦听客户端连接(默认: unix:///var/" -"run/docker.sock)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:211 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:234 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Start" -msgstr "启动" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:319 -msgid "Start Time" -msgstr "开始时间" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:789 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:790 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container.htm:5 -msgid "Stats" -msgstr "状态" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:308 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:165 -msgid "Status" -msgstr "状态" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:229 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:254 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:65 -msgid "Stop" -msgstr "停止" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/newcontainer_resolve.htm:91 -msgid "Submit" -msgstr "提交" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:86 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:101 -msgid "Subnet" -msgstr "子网" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:375 -msgid "Sysctl" -msgstr "系统控制" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:610 -msgid "Sysctl(--sysctl)" -msgstr "系统控制(--sysctl)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:611 -msgid "Sysctls (kernel parameters) options" -msgstr "系统控制(内核参数)选项" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:792 -msgid "TOP" -msgstr "TOP" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:483 -msgid "TTY (-t)" -msgstr "TTY(-t)" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:56 -msgid "TX/RX" -msgstr "发射/接收" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:579 -msgid "The hostname to use for the container" -msgstr "容器使用的主机名" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:662 -msgid "The logging configuration for this container" -msgstr "该容器的日志记录配置" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:540 -msgid "" -"The user that commands are run as inside the container.(format: name|uid[:" -"group|gid])" -msgstr "在容器中以用户运行命令。(格式:name|uid[:group|gid])" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/containers.lua:129 -msgid "" -"This page displays all containers that have been created on the connected " -"docker host." -msgstr "此页面显示在连接的Docker主机上已创建的所有容器。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/networks.lua:55 -msgid "" -"This page displays all docker networks that have been created on the " -"connected docker host." -msgstr "此页面显示在已连接的Docker主机上创建的所有Docker网络。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:367 -msgid "Tmpfs" -msgstr "Tmpfs" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:602 -msgid "Tmpfs(--tmpfs)" -msgstr "Tmpfs(--tmpfs)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/overview.lua:45 -msgid "Total Memory" -msgstr "总内存" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:697 -msgid "UID" -msgstr "UID" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:297 -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:336 -msgid "Update" -msgstr "更新" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:256 -msgid "Upgrade" -msgstr "升级" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:7 -msgid "Upload" -msgstr "上传" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:303 -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:304 -msgid "Upload Error" -msgstr "上传错误" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_file_manager.htm:294 -msgid "Upload Success" -msgstr "上传成功" - -#: applications/luci-app-dockerman/luasrc/view/dockerman/container_stats.htm:48 -msgid "Upload/Download" -msgstr "上传/下载" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/container.lua:339 -msgid "User" -msgstr "用户" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newcontainer.lua:539 -msgid "User(-u)" -msgstr "用户(-u)" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/newnetwork.lua:63 -msgid "VEPA (Virtual Ethernet Port Aggregator)" -msgstr "VEPA(虚拟以太网端口聚合器)" - -#: applications/luci-app-dockerman/luasrc/controller/dockerman.lua:41 -#: applications/luci-app-dockerman/luasrc/view/dockerman/overview.htm:187 -msgid "Volumes" -msgstr "存储卷" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/volumes.lua:73 -msgid "Volumes overview" -msgstr "卷概览" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:53 -msgid "Warning" -msgstr "警告" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/images.lua:126 -msgid "" -"When pressing the Import button, both a local image can be loaded onto the " -"system and a valid image tar can be downloaded from remote." -msgstr "" -"按下导入按钮时,既可以将本地镜像文件加载到系统上,也可以从远程下载有效的Tar格" -"式的镜像文件。" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:124 -msgid "" -"Which Port(s) can be accessed, it's not restricted by the Allowed Access " -"interfaces configuration. Use this configuration with caution!" -msgstr "设置可以被访问的端口,该配置不受“允许的访问接口”配置的限制。请谨慎使用该配置选项!" - -#: applications/luci-app-dockerman/luasrc/model/cbi/dockerman/configuration.lua:118 -msgid "" -"Which interface(s) can access containers under the bridge network, fill-in " -"Interface Name" -msgstr "哪些接口可以访问桥接网络下的容器,请填写接口名称" - -#~ msgid "Containers allowed to be accessed" -#~ msgstr "允许访问的容器" - -#~ msgid "" -#~ "Which container(s) under bridge network can be accessed, even from " -#~ "interfaces that are not allowed, fill-in Container Id or Name" -#~ msgstr "" -#~ "桥接网络下哪些容器可以访问,即使是不允许从接口访问,也要填写容器 ID 或名称" - -#~ msgid "Connect to remote endpoint" -#~ msgstr "连接到远程终端" - -#~ msgid "Global settings" -#~ msgstr "全局设定" - -#~ msgid "Path" -#~ msgstr "路径" - -#~ msgid "Please input the PATH !" -#~ msgstr "请输入合法路径!" - -#~ msgid "Setting" -#~ msgstr "设置" - -#~ msgid "Specifies where the Docker daemon will listen for client connections" -#~ msgstr "指定Docker服务端(Docker daemon)侦听客户端连接的位置" - -#~ msgid "Docker Container" -#~ msgstr "Docker 容器" - -#~ msgid "" -#~ "DockerMan is a Simple Docker manager client for LuCI, If you have any " -#~ "issue please visit:" -#~ msgstr "" -#~ "DockerMan 是一个简单的 LuCI 客户端 Docker 管理器,如果您有任何问题,请访" -#~ "问:" - -#~ msgid "Import Images" -#~ msgstr "导入镜像" - -#~ msgid "New Container" -#~ msgstr "新建容器" - -#~ msgid "New Network" -#~ msgstr "新建网络" - -#~ msgid "Macvlan Mode" -#~ msgstr "Macvlan 模式" - -#~ msgid "" -#~ "Daemon unix socket (unix:///var/run/docker.sock) or TCP Remote Hosts " -#~ "(tcp://0.0.0.0:2375), default: unix:///var/run/docker.sock" -#~ msgstr "" -#~ "守护进程 unix 套接字 (unix:///var/run/docker.sock) 或 TCP 远程主机 " -#~ "(tcp://0.0.0.0:2375),默认值:unix:///var/run/docker.sock" - -#~ msgid "Docker Daemon" -#~ msgstr "Docker 服务端" - -#~ msgid "Dockerman connect to remote endpoint" -#~ msgstr "Dockerman 连接到远程端点" - -#~ msgid "Enable" -#~ msgstr "启用" - -#~ msgid "Server Host" -#~ msgstr "服务器主机" - -#~ msgid "Contaienr Info" -#~ msgstr "容器信息" diff --git a/luci-app-dockerman/po/zh_Hans b/luci-app-dockerman/po/zh_Hans deleted file mode 100755 index 41451e4a1..000000000 --- a/luci-app-dockerman/po/zh_Hans +++ /dev/null @@ -1 +0,0 @@ -zh-cn \ No newline at end of file diff --git a/luci-app-dockerman/postinst b/luci-app-dockerman/postinst deleted file mode 100755 index b0db1cb89..000000000 --- a/luci-app-dockerman/postinst +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -/init.sh env -touch /etc/config/dockerd -uci set dockerd.dockerman=dockerman -uci set dockerd.dockerman.socket_path=`uci get dockerd.dockerman.socket_path 2&> /dev/null || echo '/var/run/docker.sock'` -uci set dockerd.dockerman.status_path=`uci get dockerd.dockerman.status_path 2&> /dev/null || echo '/tmp/.docker_action_status'` -uci set dockerd.dockerman.debug=`uci get dockerd.dockerman.debug 2&> /dev/null || echo 'false'` -uci set dockerd.dockerman.debug_path=`uci get dockerd.dockerman.debug_path 2&> /dev/null || echo '/tmp/.docker_debug'` -uci set dockerd.dockerman.remote_port=`uci get dockerd.dockerman.remote_port 2&> /dev/null || echo '2375'` -uci set dockerd.dockerman.remote_endpoint=`uci get dockerd.dockerman.remote_endpoint 2&> /dev/null || echo '0'` -uci del_list dockerd.dockerman.ac_allowed_interface='br-lan' -uci add_list dockerd.dockerman.ac_allowed_interface='br-lan' -uci commit dockerd \ No newline at end of file diff --git a/luci-app-dockerman/root/etc/init.d/dockerman b/luci-app-dockerman/root/etc/init.d/dockerman deleted file mode 100755 index 80309aeab..000000000 --- a/luci-app-dockerman/root/etc/init.d/dockerman +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=99 -USE_PROCD=1 -# PROCD_DEBUG=1 -config_load 'dockerd' -# config_get daemon_ea "dockerman" daemon_ea -_DOCKERD=/etc/init.d/dockerd - -docker_running(){ - docker version > /dev/null 2>&1 - return $? -} - -add_ports() { - [ $# -eq 0 ] && return - $($_DOCKERD running) && docker_running || return 1 - ids=$@ - for id in $ids; do - id=$(docker ps --filter "ID=$id" --quiet) - [ -z "$id" ] && { - echo "Docker containner not running"; - return 1; - } - ports=$(docker ps --filter "ID=$id" --format "{{.Ports}}") - # echo "$ports" - for port in $ports; do - echo "$port" | grep -qE "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:.*$" || continue; - [ "${port: -1}" == "," ] && port="${port:0:-1}" - local protocol="" - [ "${port%tcp}" != "$port" ] && protocol="/tcp" - [ "${port%udp}" != "$port" ] && protocol="/udp" - [ "$protocol" == "" ] && continue - port="${port%%->*}" - port="${port##*:}" - uci_add_list dockerd dockerman ac_allowed_ports "${port}${protocol}" - done - done - uci_commit dockerd -} - - -convert() { - _convert() { - _id=$1 - _id=$(docker ps --all --filter "ID=$_id" --quiet) - if [ -z "$_id" ]; then - uci_remove_list dockerd dockerman ac_allowed_container "$1" - return - fi - if /etc/init.d/dockerman add_ports "$_id"; then - uci_remove_list dockerd dockerman ac_allowed_container "$_id" - fi - } - config_list_foreach dockerman ac_allowed_container _convert - uci_commit dockerd -} - -iptables_append(){ - # Wait for a maximum of 10 second per command, retrying every millisecond - local iptables_wait_args="--wait 10 --wait-interval 1000" - if ! iptables ${iptables_wait_args} --check $@ 2>/dev/null; then - iptables ${iptables_wait_args} -A $@ 2>/dev/null - fi -} - -init_dockerman_chain(){ - iptables -N DOCKER-MAN >/dev/null 2>&1 - iptables -F DOCKER-MAN >/dev/null 2>&1 - iptables -D DOCKER-USER -j DOCKER-MAN >/dev/null 2>&1 - 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_append DOCKER-MAN -i $1 -o docker0 -j RETURN -} - -add_allowed_ports(){ - port=$1 - if [ "${port%/tcp}" != "$port" ]; then - iptables_append DOCKER-MAN -p tcp -m conntrack --ctorigdstport ${port%/tcp} --ctdir ORIGINAL -j RETURN - elif [ "${port%/udp}" != "$port" ]; then - iptables_append DOCKER-MAN -p udp -m conntrack --ctorigdstport ${port%/udp} --ctdir ORIGINAL -j RETURN - fi -} - -handle_allowed_ports(){ - config_list_foreach "dockerman" "ac_allowed_ports" add_allowed_ports -} - -handle_allowed_interface(){ - config_list_foreach "dockerman" "ac_allowed_interface" add_allowed_interface - iptables_append DOCKER-MAN -m conntrack --ctstate ESTABLISHED,RELATED -o docker0 -j RETURN >/dev/null 2>&1 - iptables_append DOCKER-MAN -m conntrack --ctstate NEW,INVALID -o docker0 -j DROP >/dev/null 2>&1 - iptables_append DOCKER-MAN -j RETURN >/dev/null 2>&1 -} - -start_service(){ - [ -x "$_DOCKERD" ] && $($_DOCKERD enabled) || return 0 - delete_dockerman_chain - $($_DOCKERD running) && docker_running || return 0 - init_dockerman_chain - handle_allowed_ports - handle_allowed_interface -} - -stop_service(){ - delete_dockerman_chain -} - -service_triggers() { - procd_add_reload_trigger 'dockerd' -} - -reload_service() { - start -} - -boot() { - sleep 5s - start -} - -extra_command "add_ports" "Add allowed ports based on the container ID(s)" -extra_command "convert" "Convert Ac allowed container to AC allowed ports" diff --git a/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman b/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman deleted file mode 100755 index 4358728a1..000000000 --- a/luci-app-dockerman/root/etc/uci-defaults/luci-app-dockerman +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -. $IPKG_INSTROOT/lib/functions.sh - -[ -x "$(command -v dockerd)" ] && chmod +x /etc/init.d/dockerman && /etc/init.d/dockerman enable >/dev/null 2>&1 -sed -i 's/self:cfgvalue(section) or {}/self:cfgvalue(section) or self.default or {}/' /usr/lib/lua/luci/view/cbi/dynlist.htm -/etc/init.d/uhttpd restart >/dev/null 2>&1 -rm -fr /tmp/luci-indexcache /tmp/luci-modulecache >/dev/null 2>&1 -touch /etc/config/dockerd -ls /etc/rc.d/*dockerd &> /dev/null && uci -q set dockerd.globals.auto_start="1" || uci -q set dockerd.globals.auto_start="0" -uci -q batch <<-EOF >/dev/null - set uhttpd.main.script_timeout="3600" - commit uhttpd - set dockerd.dockerman=dockerman - set dockerd.dockerman.socket_path='/var/run/docker.sock' - set dockerd.dockerman.status_path='/tmp/.docker_action_status' - set dockerd.dockerman.debug='false' - set dockerd.dockerman.debug_path='/tmp/.docker_debug' - set dockerd.dockerman.remote_endpoint='0' - - del_list dockerd.dockerman.ac_allowed_interface='br-lan' - add_list dockerd.dockerman.ac_allowed_interface='br-lan' - - commit dockerd -EOF -# remove dockerd firewall -config_load dockerd -remove_firewall(){ - cfg=${1} - uci_remove dockerd ${1} -} -config_foreach remove_firewall firewall -# Convert ac_allowed_container to ac_allowed_ports -(sleep 30s && /etc/init.d/dockerman convert;/etc/init.d/dockerman restart) & - -exit 0 diff --git a/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json b/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json deleted file mode 100755 index 78c2c6418..000000000 --- a/luci-app-dockerman/root/usr/share/rpcd/acl.d/luci-app-dockerman.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-dockerman": { - "description": "Grant UCI access for luci-app-dockerman", - "read": { - "uci": [ "dockerd" ] - }, - "write": { - "uci": [ "dockerd" ] - } - } -} diff --git a/luci-app-mptcp/luasrc/model/cbi/mptcp.lua b/luci-app-mptcp/luasrc/model/cbi/mptcp.lua index a36c3d391..53fba62e8 100755 --- a/luci-app-mptcp/luasrc/model/cbi/mptcp.lua +++ b/luci-app-mptcp/luasrc/model/cbi/mptcp.lua @@ -15,9 +15,13 @@ o:value("disable", translate("disable")) o = s:option(ListValue, "mptcp_checksum", translate("Multipath TCP checksum")) o:value(1, translate("enable")) o:value(0, translate("disable")) -o = s:option(ListValue, "mptcp_debug", translate("Multipath Debug")) -o:value(1, translate("enable")) -o:value(0, translate("disable")) + +if uname.release:sub(1,4) ~= "5.15" and uname.release:sub(1,1) ~= "6" then + o = s:option(ListValue, "mptcp_debug", translate("Multipath Debug")) + o:value(1, translate("enable")) + o:value(0, translate("disable")) +end + o = s:option(ListValue, "mptcp_path_manager", translate("Multipath TCP path-manager"), translate("Default is fullmesh")) o:value("default", translate("default")) o:value("fullmesh", "fullmesh") @@ -61,22 +65,73 @@ end -- if tonumber(uname.release:sub(1,4)) >= 5.15 then if uname.release:sub(1,4) == "5.15" or uname.release:sub(1,1) == "6" then - o = s:option(Value, "mptcp_subflows", translate("specifies the maximum number of additional subflows allowed for each MPTCP connection")) + if uname.release:sub(1,1) == "6" then + -- Only available since 5.19 + o = s:option(ListValue, "mptcp_pm_type", translate("Path Manager type")) + o:value(0, translate("In-kernel path manager")) + o:value(1, translate("Userspace path manager")) + o.default = 0 + end + + o = s:option(ListValue, "mptcp_disable_initial_config", translate("Initial MPTCP configuration")) + o:depends("mptcp_pm_type",1) + o:value("0", translate("enable")) + o:value("1", translate("disable")) + o.default = "0" + + o = s:option(ListValue, "mptcp_force_multipath", translate("Force Multipath configuration")) + o:depends("mptcp_pm_type",1) + o:value("1", translate("enable")) + o:value("0", translate("disable")) + o.default = "1" + + o = s:option(ListValue, "mptcpd_enable", translate("Enable MPTCPd")) + o:depends("mptcp_pm_type",1) + o:value("enable", translate("enable")) + o:value("disable", translate("disable")) + o.default = "disable" + + o = s:option(DynamicList, "mptcpd_path_manager", translate("MPTCPd path managers")) + for dir in io.popen([[cd /usr/lib/mptcpd && ls -1 *.so | sed 's/.so//g']]):lines() do + o:value(dir, dir) + end + o:depends("mptcp_pm_type",1) + + o = s:option(DynamicList, "mptcpd_plugins", translate("MPTCPd plugins")) + for dir in io.popen([[cd /usr/lib/mptcpd && ls -1 *.so | sed 's/.so//g']]):lines() do + o:value(dir, dir) + end + o:depends("mptcp_pm_type",1) + + o = s:option(DynamicList, "mptcpd_addr_flags", translate("MPTCPd Address annoucement flags")) + o:value("subflow","subflow") + o:value("signal","signal") + o:value("backup","backup") + o:value("fullmesh","fullmesh") + o:depends("mptcp_pm_type",1) + + o = s:option(DynamicList, "mptcpd_notify_flags", translate("MPTCPd Address notification flags")) + o:value("existing","existing") + o:value("skip_link_local","skip_link_local") + o:value("skip_loopback","skip_loopback") + o:depends("mptcp_pm_type",1) + + o = s:option(Value, "mptcp_subflows", translate("Max subflows"),translate("specifies the maximum number of additional subflows allowed for each MPTCP connection")) o.datatype = "uinteger" o.rmempty = false o.default = 3 - - o = s:option(Value, "mptcp_add_addr_accepted", translate("specifies the maximum number of ADD_ADDR suboptions accepted for each MPTCP connection")) - o.datatype = "uinteger" - o.rmempty = false - o.default = 1 - o = s:option(Value, "mptcp_stale_loss_cnt", translate("The number of MPTCP-level retransmission intervals with no traffic and pending outstanding data on a given subflow required to declare it stale")) + o = s:option(Value, "mptcp_stale_loss_cnt", translate("Retranmission intervals"),translate("The number of MPTCP-level retransmission intervals with no traffic and pending outstanding data on a given subflow required to declare it stale. A low stale_loss_cnt value allows for fast active-backup switch-over, an high value maximize links utilization on edge scenarios e.g. lossy link with high BER or peer pausing the data processing.")) o.datatype = "uinteger" o.rmempty = false o.default = 4 - o = s:option(Value, "mptcp_add_addr_timeout", translate("Set the timeout after which an ADD_ADDR control message will be resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message.")) + o = s:option(Value, "mptcp_add_addr_accepted", translate("Max add address"),translate("specifies the maximum number of ADD_ADDR (add address) suboptions accepted for each MPTCP connection")) + o.datatype = "uinteger" + o.rmempty = false + o.default = 1 + + o = s:option(Value, "mptcp_add_addr_timeout", translate("Control message timeout"),translate("Set the timeout after which an ADD_ADDR (add address) control message will be resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message.")) o.datatype = "uinteger" o.rmempty = false o.default = 120 diff --git a/luci-app-omr-bypass/Makefile b/luci-app-omr-bypass/Makefile old mode 100644 new mode 100755 index 2969ef549..7b83f4c8c --- a/luci-app-omr-bypass/Makefile +++ b/luci-app-omr-bypass/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI Interface to bypass domains #LUCI_DEPENDS:=+dnsmasq-full +shadowsocks-libev-ss-rules +(LINUX_5_4||LINUX_5_15||TARGET_x86_64):iptables-mod-ndpi +iptables-mod-extra +(LINUX_5_4||LINUX_5_15||TARGET_x86_64):kmod-ipt-ndpi +iptables LUCI_DEPENDS:=+dnsmasq-full +shadowsocks-libev-ss-rules +iptables-mod-extra +iptables +sqlite3-cli -ifneq ($(CONFIG_TARGET_ramips),) +ifneq ($(CONFIG_TARGET_ramips),y) #LUCI_DEPENDS+=+(LINUX_5_4||LINUX_5_15):iptables-mod-ndpi +(LINUX_5_4||LINUX_5_15):kmod-ipt-ndpi LUCI_DEPENDS+=+iptables-mod-ndpi +kmod-ipt-ndpi endif diff --git a/luci-app-omr-bypass/htdocs/luci-static/resources/view/services/omr-bypass.js b/luci-app-omr-bypass/htdocs/luci-static/resources/view/services/omr-bypass.js old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/de/omr-bypass.po b/luci-app-omr-bypass/po/de/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/de/omr-bypass.po~ b/luci-app-omr-bypass/po/de/omr-bypass.po~ old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/fr/omr-bypass.po b/luci-app-omr-bypass/po/fr/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/it/omr-bypass.po b/luci-app-omr-bypass/po/it/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/it/omr-bypass.po~ b/luci-app-omr-bypass/po/it/omr-bypass.po~ old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/oc/omr-bypass.po b/luci-app-omr-bypass/po/oc/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/oc/omr-bypass.po~ b/luci-app-omr-bypass/po/oc/omr-bypass.po~ old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/ru/omr-bypass.po b/luci-app-omr-bypass/po/ru/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/templates/omr-bypass.pot b/luci-app-omr-bypass/po/templates/omr-bypass.pot old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/po/zh_Hans/omr-bypass.po b/luci-app-omr-bypass/po/zh_Hans/omr-bypass.po old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/etc/config/omr-bypass b/luci-app-omr-bypass/root/etc/config/omr-bypass old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/etc/firewall.omr-bypass b/luci-app-omr-bypass/root/etc/firewall.omr-bypass old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/usr/share/luci/menu.d/luci-app-omr-bypass.json b/luci-app-omr-bypass/root/usr/share/luci/menu.d/luci-app-omr-bypass.json old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/usr/share/omr-bypass/omr-bypass-proto.lst b/luci-app-omr-bypass/root/usr/share/omr-bypass/omr-bypass-proto.lst old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/usr/share/omr-bypass/omr-bypass.db b/luci-app-omr-bypass/root/usr/share/omr-bypass/omr-bypass.db old mode 100644 new mode 100755 diff --git a/luci-app-omr-bypass/root/usr/share/rpcd/acl.d/luci-app-omr-bypass.json b/luci-app-omr-bypass/root/usr/share/rpcd/acl.d/luci-app-omr-bypass.json old mode 100644 new mode 100755 diff --git a/luci-app-openmptcprouter/luasrc/controller/openmptcprouter.lua b/luci-app-openmptcprouter/luasrc/controller/openmptcprouter.lua index 5a0cb0566..1f979d871 100755 --- a/luci-app-openmptcprouter/luasrc/controller/openmptcprouter.lua +++ b/luci-app-openmptcprouter/luasrc/controller/openmptcprouter.lua @@ -415,6 +415,7 @@ function wizard_add() local downloadspeed = luci.http.formvalue("cbid.sqm.%s.download" % intf) or "0" local uploadspeed = luci.http.formvalue("cbid.sqm.%s.upload" % intf) or "0" + local testspeed = luci.http.formvalue("cbid.sqm.%s.testspeed" % intf) or "0" if not ucic:get("qos",intf) ~= "" then ucic:set("qos",intf,"interface") @@ -438,7 +439,7 @@ function wizard_add() ucic:set("sqm",intf,"script","piece_of_cake.qos") ucic:set("sqm",intf,"qdisc_advanced","0") ucic:set("sqm",intf,"linklayer","atm") - ucic:set("sqm",intf,"overhead","40") + ucic:set("sqm",intf,"overhead","44") ucic:set("sqm",intf,"enabled","0") ucic:set("sqm",intf,"debug_logging","0") ucic:set("sqm",intf,"verbosity","5") @@ -454,6 +455,10 @@ function wizard_add() ucic:set("sqm",intf,"qdisc","cake") ucic:set("sqm",intf,"script","piece_of_cake.qos") end + ucic:set("openmptcprouter",intf,"testspeed",testspeed) + if testspeed == "1" then + ucic:delete("openmptcprouter",intf,"testspeed_lc") + end if downloadspeed ~= "0" and downloadspeed ~= "" then if sqmautorate == "1" and (ucic:get("network",intf,"downloadspeed") ~= downloadspeed or ucic:get("sqm",intf,"max_download") == "" or ucic:get("sqm",intf,"download") == "0") then ucic:set("sqm",intf,"download",math.ceil(downloadspeed*65/100)) @@ -551,17 +556,22 @@ function wizard_add() vpn_intf = "bonding-omrvpn" ucic:set("network","omrvpn","proto","bonding") end - if downloadmax ~= 0 and uploadmax ~= 0 then - ucic:set("sqm","omrvpn","enabled","1") - ucic:set("sqm","omrvpn","max_download",downloadmax) - ucic:set("sqm","omrvpn","max_upload",uploadmax) - ucic:set("sqm","omrvpn","download",math.ceil(downloadmax*50/100)) - ucic:set("sqm","omrvpn","min_download",math.ceil(downloadmax*8/100)) - ucic:set("sqm","omrvpn","upload",math.ceil(uploadmax*50/100)) - ucic:set("sqm","omrvpn","min_upload",math.ceil(uploadmax*8/100)) - else - ucic:set("sqm","omrvpn","enabled","0") - end + --if downloadmax ~= 0 and uploadmax ~= 0 then + -- ucic:set("sqm","omrvpn","enabled","1") + -- ucic:set("sqm","omrvpn","max_download",downloadmax) + -- ucic:set("sqm","omrvpn","max_upload",uploadmax) + -- ucic:set("sqm","omrvpn","download",math.ceil(downloadmax*50/100)) + -- ucic:set("sqm","omrvpn","min_download",math.ceil(downloadmax*8/100)) + -- ucic:set("sqm","omrvpn","upload",math.ceil(uploadmax*50/100)) + -- ucic:set("sqm","omrvpn","min_upload",math.ceil(uploadmax*8/100)) + --else + -- ucic:set("sqm","omrvpn","enabled","0") + --end + + ucic:set("sqm","omrvpn","enabled","1") + ucic:set("sqm","omrvpn","download","0") + ucic:set("sqm","omrvpn","upload","0") + if vpn_intf ~= "" then ucic:set("network","omrvpn","device",vpn_intf) ucic:set("sqm","omrvpn","interface",vpn_intf) @@ -619,7 +629,7 @@ function wizard_add() ucic:set("openmptcprouter",server,"username",openmptcprouter_vps_username:gsub("%s+", "")) ucic:set("openmptcprouter",server,"password",openmptcprouter_vps_key:gsub("%s+", "")) ucic:set("openmptcprouter",server,"disabled",openmptcprouter_vps_disabled) - if ucic:get("openmptcprouter",server,"ip") ~= aserverips then + if ucic:get_list("openmptcprouter",server,"ip") ~= aserverips then ucic:set_list("openmptcprouter",server,"ip",aserverips) if ucic:get("openmptcprouter",server,"master") == "1" then ucic:set("openmptcprouter",server,"get_config","1") @@ -805,6 +815,7 @@ function wizard_add() local encryption = luci.http.formvalue("encryption") if encryption == "none" then + ucic:set("openmptcprouter","settings","encryption","none") ucic:set("shadowsocks-libev","sss0","method","none") ucic:set("shadowsocks-libev","sss1","method","none") ucic:set("openvpn","omr","cipher","none") @@ -812,6 +823,7 @@ function wizard_add() ucic:set("v2ray","omrout","s_vmess_user_security","none") ucic:set("v2ray","omrout","s_vless_user_security","none") elseif encryption == "aes-256-gcm" then + ucic:set("openmptcprouter","settings","encryption","aes-256-gcm") ucic:set("shadowsocks-libev","sss0","method","aes-256-gcm") ucic:set("shadowsocks-libev","sss1","method","aes-256-gcm") ucic:set("glorytun","vpn","chacha20","0") @@ -821,6 +833,7 @@ function wizard_add() ucic:set("v2ray","omrout","s_vmess_user_security","aes-128-gcm") ucic:set("v2ray","omrout","s_vless_user_security","aes-128-gcm") elseif encryption == "aes-256-cfb" then + ucic:set("openmptcprouter","settings","encryption","aes-256-cfb") ucic:set("shadowsocks-libev","sss0","method","aes-256-cfb") ucic:set("shadowsocks-libev","sss1","method","aes-256-cfb") ucic:set("glorytun","vpn","chacha20","0") @@ -830,6 +843,7 @@ function wizard_add() ucic:set("v2ray","omrout","s_vmess_user_security","aes-128-gcm") ucic:set("v2ray","omrout","s_vless_user_security","aes-128-gcm") elseif encryption == "chacha20-ietf-poly1305" then + ucic:set("openmptcprouter","settings","encryption","chacha20") ucic:set("shadowsocks-libev","sss0","method","chacha20-ietf-poly1305") ucic:set("shadowsocks-libev","sss1","method","chacha20-ietf-poly1305") ucic:set("glorytun","vpn","chacha20","1") @@ -838,6 +852,8 @@ function wizard_add() ucic:set("mlvpn","general","cleartext_data","0") ucic:set("v2ray","omrout","s_vmess_user_security","chacha20-poly1305") ucic:set("v2ray","omrout","s_vless_user_security","chacha20-poly1305") + else + ucic:set("openmptcprouter","settings","encryption","other") end ucic:save("openvpn") ucic:save("glorytun") diff --git a/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm b/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm index 69d7b5a81..e30f5dfc0 100755 --- a/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm +++ b/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm @@ -269,13 +269,18 @@

@@ -988,12 +993,22 @@ end %>
+ +
+ checked<% end %> /> +
+
+ <%:Run an automatic speedtest to calculate max download & upload speed.%> +
+
+
+

- <%:Used by Glorytun UDP and SQM/QoS if enabled. 0 to use default value.%> + <%:Used by Glorytun UDP and SQM/QoS if enabled.%>
-
+

- <%:Used by Glorytun UDP and SQM/QoS if enabled. 0 to use default value.%> + <%:Used by Glorytun UDP and SQM/QoS if enabled.%>