uci = require "luci.model.uci".cursor() local fs = require "nixio.fs" local json = require "luci.jsonc" m = Map("fogvdn", translate("FOGVDN Node")) s = m:section(NamedSection, "main", "main", translate("Main")) act_status = s:option(DummyValue, "act_status", translate("Status")) act_status.template = "pcdn/act_status" enabled = s:option(Flag, "enable", translate("Enable")) enabled.default = 0 node_info_file = "/etc/pear/pear_monitor/node_info.json" if fs.access(node_info_file) then local node_info = fs.readfile(node_info_file) node_info = json.parse(node_info) for k,v in pairs(node_info) do node_info_file = "/etc/pear/pear_monitor/node_info.json" if fs.access(node_info_file) then local node_info = fs.readfile(node_info_file) node_info = json.parse(node_info) for k,v in pairs(node_info) do if k == "node_id" then option = s:option(DummyValue, "_"..k,translate(k)) option.value = v end end end storage_info_file = "/etc/pear/pear_monitor/storage_info.json" if fs.access(storage_info_file) then local storage_info = fs.readfile(storage_info_file) storage_info = json.parse(storage_info) for k,v in pairs(storage_info) do if k == "os_drive_serial" then option = s:option(DummyValue, "_"..k,translate(k)) option.value = v end end end option = s:option(DummyValue, "_"..k,translate(k)) option.value = v end end end openfog_link=s:option(DummyValue, "openfog_link", translate("")) openfog_link.description = translate("OpenFogOS Official Website") s = m:section(TypedSection, "instance", translate("Settings")) s.anonymous = true s.description = translate("Fogvdn Settings") username = s:option(Value, "username", translate("username")) username.description = translate("") region = s:option(Value, "region", translate("Region")) region.optional = true region.template="cbi/city" isp = s:option(Value, "isp", translate("ISP")) isp.optional = true isp:value("电信", translate("China Telecom")) isp:value("移动", translate("China Mobile")) isp:value("联通", translate("China Unicom")) per_line_up_bw = s:option(Value, "per_line_up_bw", translate("Per Line Up BW")) per_line_up_bw.template = "cbi/digitonlyvalue" per_line_up_bw.datatype = "uinteger" per_line_down_bw = s:option(Value, "per_line_down_bw", translate("Per Line Down BW")) per_line_down_bw.template = "cbi/digitonlyvalue" per_line_down_bw.datatype = "uinteger" limited_memory = s:option(Value, "limited_memory", translate("Limited Memory")) limited_memory.optional = true limited_memory.template = "cbi/digitonlyvalue" limited_memory.datatype = "range(0, 100)" -- 0-100% limited_storage = s:option(Value, "limited_storage", translate("Limited Storage")) limited_storage.optional = true limited_storage.template = "cbi/digitonlyvalue" limited_storage.datatype = "range(0, 100)" -- 0-100% limited_area = s:option(Value, "limited_area", translate("Limited Area")) limited_area.default = "2" limited_area:value("-1", "不设置:若不确定运营商对流量出省的限制情况,建议选择该项") limited_area:value("0", "全国调度:流量将会向全国调度,出省比例较高,可能会导致运营商的限制") limited_area:value("1", "本省调度:流量只会向所在省份内调度,是比较安全的调度模式,但跑量可能会降低") limited_area:value("2", "大区调度:流量只会向所在大区内调度,出省比例较低,是安全性和跑量之间较为均衡的模式") -- 限制地区 -1 不设置(采用openfogos默认) 0 全国调度,1 省份调度,2 大区调度 nics = s:option(DynamicList,"nics",translate("netdev")) -- uci:foreach("multiwan","multiwan",function (instance) -- nics:value(instance["tag"]) -- end -- ) --list /sys/class/net, filter bridge device cmd="/usr/share/pcdn/check_netdev get_netdevs" json_dump=luci.sys.exec(cmd) devs=json.parse(json_dump) for k,v in pairs(devs) do nics:value(k,k.." ["..v.."]") end storage = s:option(DynamicList, "storage", translate("Storage")) storage.default = "/opt/openfogos" storage.description = translate("Warnning: System directory is not allowed!") --filter start with /etc /usr /root /var /tmp /dev /proc /sys /overlay /rom and root mount_point = {} cmd="/usr/share/pcdn/check_mount_ponit mount_point" json_dump=luci.sys.exec(cmd) mount_point=json.parse(json_dump) for k,v in pairs(mount_point) do storage:value(k,k.."("..v..")") end btn = s:option(Button, "_filter", "") btn.inputtitle = "应用最佳存储设置" btn.description = "为避免木桶效应,点击估算最佳设置" btn.inputstyle = "apply" -- 获取表中元素的索引 table.indexOf = function(tbl, value) for i, v in ipairs(tbl) do if v == value then return i end end return -1 end -- 拷贝表 table.copy = function(tbl) local copy = {} for k, v in pairs(tbl) do copy[k] = v end return copy end -- 解析并转换大小单位 function parseSize(size) if type(size) ~= "string" then return 0 end local unit = {"B", "K", "M", "G", "T"} local num, u = string.match(size, "^(%d+%.?%d*)([KMGT]?)$") if not num then return 0 end local i = table.indexOf(unit, u) -- 如果没有找到单位,默认为字节 if i == -1 then return tonumber(num) else return tonumber(num) * (1024 ^ i) end end -- 获取最佳存储方案 function getOptimalSolution(numsObjArray) if type(numsObjArray) ~= "table" or #numsObjArray == 0 then return {} end -- 拷贝并按大小排序 local nums = {} for _, v in ipairs(numsObjArray) do table.insert(nums, {name = v.name, size = v.size}) end table.sort(nums, function(a, b) return parseSize(a.size) < parseSize(b.size) end) local max = 0 local optimal = {} while #nums > 0 do local temp = parseSize(nums[1].size) * #nums if temp > max then max = temp optimal = table.copy(nums) end table.remove(nums, 1) -- 移除第一个元素 end -- 提取名称并排序 local result = {} for _, v in ipairs(optimal) do table.insert(result, v.name) end table.sort(result) return result end function btn.write(self, section) local numsObjArray = {} for k,v in pairs(mount_point) do table.insert(numsObjArray, {name = k, size = v}) end local optimalStorage = getOptimalSolution(numsObjArray) self.map:set(section, "storage", optimalStorage) end return m