luci-app-diskman: sync with upstream source

This commit is contained in:
CN_SZTL 2020-02-06 20:29:07 +08:00
parent 8259f4fbe8
commit a68e3922d2
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
7 changed files with 291 additions and 78 deletions

View File

@ -1,11 +1,6 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-diskman>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.util"

View File

@ -1,11 +1,6 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-diskman>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.util"
@ -15,13 +10,43 @@ local uuid = arg[1]
if not uuid then luci.http.redirect(luci.dispatcher.build_url("admin/system/diskman")) end
m = SimpleForm("btrfs", translate("Btrfs"), translate("Manage Btrfs."))
-- mount subv=/ to tempfs
mount_point = "/tmp/.btrfs_tmp"
nixio.fs.mkdirr(mount_point)
luci.util.exec("umount "..mount_point .. " >/dev/null 2>&1")
luci.util.exec("mount -o subvol=/ -U "..uuid.." "..mount_point)
m = SimpleForm("btrfs", translate("Btrfs"), translate("Manage Btrfs"))
m.submit = false
m.reset = false
m.redirect = luci.dispatcher.build_url("admin/system/diskman")
-- 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, mount_point = dm.get_btrfs_subv(uuid)
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"))
@ -77,14 +102,21 @@ btn_set_default.write = function(self, section, value)
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 == "/" 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
@ -105,7 +137,7 @@ btn_remove.write = function(self, section, value)
end
end
-- snapshot
-- local snapshot_list = dm.get_btrfs_subv(uuid, 1)
-- 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"))
@ -126,7 +158,7 @@ end
-- end
-- new snapshots
local s_snapshot = m:section(SimpleSection, "New Snapshot")
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"))
v_sorce.placeholder = "/data"
@ -148,7 +180,7 @@ v_dest.write = function(self, section, value)
end
local btn_snp_create = s_snapshot:option(Button, "_snp_create")
btn_snp_create.title = " "
btn_snp_create.inputtitle = translate("Create Snapshot")
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

View File

@ -1,11 +1,6 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-diskman>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.util"
@ -85,8 +80,9 @@ if dm.command.btrfs 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, "devices", translate("Devices"))
table_btrfs:option(DummyValue, "size_formated", translate("Size"))
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
@ -212,11 +208,17 @@ v_mount_option.render = function(self, section, scope)
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 #mount_point[section].mount_options > 50 then mount_point[section].mount_options = mount_point[section].mount_options.. " " end
mount_point[section].mount_options= mount_point[section].mount_options.. k
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.. " <br>"
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
@ -270,7 +272,7 @@ end
if dm.command.btrfs then
local blabel, bmembers, blevel
tab_section.tabs.btrfs = translate("Btrfs")
local r = m:section(SimpleSection, translate("Btrfs Multiple Devices Creation"))
local r = m:section(SimpleSection, translate("Multiple Devices Btrfs Creation"))
r.template="diskman/cbi/xnullsection"
r.config = "btrfs"
local btrfs_label = r:option(Value, "_blabel", translate("Btrfs Label"))

View File

@ -1,11 +1,6 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-diskman>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.util"
@ -37,7 +32,7 @@ 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 "))
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
@ -161,7 +156,9 @@ if not disk_info.p_table:match("Raid") then
if disk_info.p_table == "MBR" then
s_partition_table:option(DummyValue, "type", translate("Type"))
end
s_partition_table:option(DummyValue, "useage", translate("Useage"))
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"))
s_partition_table:option(DummyValue, "mount_point", translate("Mount Point"))
local val_fs = s_partition_table:option(Value, "fs", translate("File System"))
val_fs.forcewrite = true

View File

@ -1,17 +1,12 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-diskman>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
require "luci.util"
local ver = require "luci.version"
local CMD = {"parted", "mdadm", "blkid", "smartctl", "df", "sgdisk", "btrfs", "mergerfs", "snapraid", "lsblk"}
local CMD = {"parted", "mdadm", "blkid", "smartctl", "df", "sgdisk", "btrfs", "mergerfs", "snapraid"}
local d = {command ={}}
for _, cmd in ipairs(CMD) do
@ -21,7 +16,7 @@ end
local mounts = nixio.fs.readfile("/proc/mounts") or ""
local swaps = nixio.fs.readfile("/proc/swaps") or ""
local df = luci.sys.exec(d.command.df) or ""
local df = luci.sys.exec(d.command.df .. " -B1") or ""
function byte_format(byte)
local suff = {"B", "KB", "MB", "GB", "TB"}
@ -142,11 +137,16 @@ local get_mount_point = function(partition)
end
local get_partition_useage = function(partition)
-- return used, free, usage
local get_partition_usage = function(partition)
if not nixio.fs.access("/dev/"..partition) then return false end
local useage = df:match("\n/dev/" .. partition .. "%s+%d+%s+%d+%s+%d+%s+([0-9]+)%%%s")
useage = useage and (useage .. "%") or false
return useage
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) or 0
free = free and tonumber(free) or 0
return used, free, usage
end
local get_parted_info = function(device)
@ -195,7 +195,15 @@ local get_parted_info = function(device)
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 "-"
partition_temp["useage"] = partition_temp["mount_point"]~="-" and get_partition_useage(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
@ -288,8 +296,8 @@ d.get_disk_info = function(device, wakeup)
{
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, useage },
2 = { number, name, sec_start, sec_end, size, size_mounted, fs, tag_name, type, flags, mount_point, useage },
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
@ -538,7 +546,7 @@ d.gen_mdadm_config = function()
end
-- list btrfs filesystem device
-- {uuid={uuid, label, devices, size, used}...}
-- {uuid={uuid, label, members, size, used}...}
d.list_btrfs_devices = function()
local btrfs_device = {}
if not d.command.btrfs then return btrfs_device end
@ -561,7 +569,7 @@ d.list_btrfs_devices = function()
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]["devices"] = btrfs_device[_uuid]["devices"] and btrfs_device[_uuid]["devices"]..", "..device or device
btrfs_device[_uuid]["members"] = btrfs_device[_uuid]["members"] and btrfs_device[_uuid]["members"]..", "..device or device
end
end
return btrfs_device
@ -575,22 +583,65 @@ d.create_btrfs = function(blabel, blevel, 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}...}, mount_point
d.get_btrfs_subv = function(uuid, snapshot)
-- {id={id, gen, top_level, path, snapshots, otime, default_subvolume}...}
d.get_btrfs_subv = function(m_point, snapshot)
local subvolume = {}
if not uuid or not d.command.lsblk or not d.command.btrfs then return subvolume end
-- check mounted device & get mount point
-- local m_point = luci.util.exec(d.command.lsblk .. " -o UUID,MOUNTPOINT | awk '{if($1==\""..uuid.."\") print $2}'")
-- clear sapce and \n
-- m_point = m_point and string.gsub(m_point, "[\n%s]+", "")
-- if not m_point or m_point =="" then
m_point = "/tmp/.btrfs_tmp"
nixio.fs.mkdirr(m_point)
luci.util.exec("umount "..m_point .. " >/dev/null 2>&1")
luci.util.exec("mount -o subvol=/ -U "..uuid.." "..m_point)
-- os.execute("sleep " .. 0.5)
-- end
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
@ -603,23 +654,27 @@ if not snapshot then
cmd = d.command.btrfs .. " subvolume show ".. m_point
for _, line in ipairs(luci.util.execl(cmd)) do
if not section_snap then
local uuid = line:match("^%s-UUID:%s+([^%s]+)")
local otime = line:match("^%s+Creation time:%s+(.+)")
local id = line:match("^%s+Subvolume ID:%s+([^%s]+)")
if uuid then
_uuid = uuid
elseif otime then
_otime = otime
elseif id then
_id = id
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"
section_snap = true
end
else
local snapshot = line:match("^%s+(.+)")
_snap = _snap and (_snap ..", /".. snapshot) or ("/"..snapshot)
if snapshot then
_snap = _snap and (_snap ..", /".. snapshot) or ("/"..snapshot)
end
end
end
luci.util.perror(_uuid)
luci.util.perror(_otime)
luci.util.perror(_id)
luci.util.perror(_snap)
luci.util.perror(_uuid)
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
@ -666,7 +721,7 @@ end
-- if m_point == "/tmp/.btrfs_tmp" then
-- luci.util.exec("umount " .. m_point)
-- end
return subvolume, m_point
return subvolume
end
return d

View File

@ -61,7 +61,7 @@ msgstr "Sektor początkowy"
msgid "End Sector"
msgstr "Sektor końcowy"
msgid "Useage"
msgid "Usage"
msgstr "Użycie"
msgid "Model"
@ -126,3 +126,66 @@ msgstr "Informacja o partycjach"
msgid "Default 2048 sector alignment, support +size{b,k,m,g,t} in End Sector"
msgstr "Sektory wyrównywane są do wielokrotności 2048, sektor końcowy można podać jako rozmiar w postaci +size{b,k,m,g,t}"
msgid "Multiple Devices Btrfs Creation"
msgstr "Kreator urządzeń Btrfs"
msgid "Label"
msgstr "Etykieta"
msgid "Btrfs Label"
msgstr "Etykieta Btrfs"
msgid "Btrfs Raid Level"
msgstr "Poziom Raid Btrfs"
msgid "Btrfs Member"
msgstr "Członek Btrfs"
msgid "Create Btrfs"
msgstr "Utwórz Btrfs"
msgid "New Snapshot"
msgstr "Nowy obraz"
msgid "SubVolumes"
msgstr "SubVolumes"
msgid "Top Level"
msgstr "Top Level"
msgid "Manage Btrfs"
msgstr "Zarządzaj Btrfs"
msgid "Otime"
msgstr "Otime"
msgid "Snapshots"
msgstr "Obrazy"
msgid "Set Default"
msgstr "Ustaw domyślnie"
msgid "Source Path"
msgstr "Ścieżka źródłowa"
msgid "Readonly"
msgstr "Tylko do odczytu"
msgid "Delete"
msgstr "Usuń"
msgid "Create"
msgstr "Utwórz"
msgid "Destination Path (optional)"
msgstr "Ścieżka docelowa (opcjonalnie)"
msgid "Metadata"
msgstr "Metadata"
msgid "Data"
msgstr "Data"
msgid "Btrfs Info"
msgstr "Informacja o Btrfs"

View File

@ -61,8 +61,14 @@ msgstr "起始扇区"
msgid "End Sector"
msgstr "中止扇区"
msgid "Useage"
msgstr "使用情况"
msgid "Usage"
msgstr "用量"
msgid "Used"
msgstr "已使用"
msgid "Free Space"
msgstr "空闲空间"
msgid "Model"
msgstr "主机型号"
@ -126,3 +132,66 @@ 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 信息"