summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2019-09-21 18:36:31 +0200
committerJo-Philipp Wich <jo@mein.io>2019-09-21 18:36:31 +0200
commit71e265a7f038f172eada95576496ef240a9c83e7 (patch)
treea592edaec6bcc584ac11b014018f2a9b43ee1f00
parent54cab2f26be6c925cab8651c254380877474a130 (diff)
luci-mod-system: remplement fstab settings as client side view
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json11
-rw-r--r--modules/luci-mod-system/htdocs/luci-static/resources/view/system/mounts.js428
-rw-r--r--modules/luci-mod-system/luasrc/controller/admin/system.lua4
-rw-r--r--modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab.lua272
-rw-r--r--modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/mount.lua158
-rw-r--r--modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/swap.lua54
6 files changed, 436 insertions, 491 deletions
diff --git a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json
index 32cb10596..af06d840d 100644
--- a/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json
+++ b/modules/luci-base/root/usr/share/rpcd/acl.d/luci-base.json
@@ -25,13 +25,15 @@
"/*": [ "list" ],
"/etc/crontabs/root": [ "read" ],
"/etc/dropbear/authorized_keys": [ "read" ],
+ "/etc/filesystems": [ "read" ],
"/etc/rc.local": [ "read" ],
+ "/proc/filesystems": [ "read" ],
"/proc/sys/kernel/hostname": [ "read" ]
},
"ubus": {
"file": [ "list", "read", "stat" ],
"iwinfo": [ "assoclist", "freqlist", "txpowerlist", "countrylist" ],
- "luci": [ "getBoardJSON", "getDUIDHints", "getHostHints", "getIfaddrs", "getInitList", "getLocaltime", "getTimezones", "getDHCPLeases", "getLEDs", "getNetworkDevices", "getUSBDevices", "getWirelessDevices", "getSwconfigFeatures", "getSwconfigPortState" ],
+ "luci": [ "getBoardJSON", "getDUIDHints", "getHostHints", "getIfaddrs", "getInitList", "getLocaltime", "getTimezones", "getDHCPLeases", "getLEDs", "getNetworkDevices", "getUSBDevices", "getWirelessDevices", "getSwconfigFeatures", "getSwconfigPortState", "getBlockDevices", "getMountPoints" ],
"network.device": [ "status" ],
"network.interface": [ "dump" ],
"network": [ "get_proto_handlers" ],
@@ -45,12 +47,13 @@
"/etc/crontabs/root": [ "write" ],
"/etc/dropbear/authorized_keys": [ "write" ],
"/etc/luci-uploads/*": [ "write" ],
- "/etc/rc.local": [ "write" ]
+ "/etc/rc.local": [ "write" ],
+ "/sbin/block": [ "exec" ]
},
"ubus": {
- "file": [ "write", "remove" ],
+ "file": [ "write", "remove", "exec" ],
"iwinfo": [ "scan" ],
- "luci": [ "setInitAction", "setLocaltime", "setPassword" ],
+ "luci": [ "setInitAction", "setLocaltime", "setPassword", "setBlockDetect", "setUmount" ],
"uci": [ "add", "apply", "confirm", "delete", "order", "set", "rename" ]
},
"uci": [ "*" ]
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/mounts.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/mounts.js
new file mode 100644
index 000000000..b9028b20e
--- /dev/null
+++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/mounts.js
@@ -0,0 +1,428 @@
+'use strict';
+'require uci';
+'require rpc';
+'require form';
+
+var callBlockDevices, callMountPoints, callBlockDetect, callUmount,
+ callFileRead, callFileStat, callFileExec;
+
+callBlockDevices = rpc.declare({
+ object: 'luci',
+ method: 'getBlockDevices',
+ expect: { '': {} }
+});
+
+callMountPoints = rpc.declare({
+ object: 'luci',
+ method: 'getMountPoints',
+ expect: { result: [] }
+});
+
+callBlockDetect = rpc.declare({
+ object: 'luci',
+ method: 'setBlockDetect',
+ expect: { result: false }
+});
+
+callUmount = rpc.declare({
+ object: 'luci',
+ method: 'setUmount',
+ params: [ 'path' ],
+ expect: { result: false }
+});
+
+callFileRead = rpc.declare({
+ object: 'file',
+ method: 'read',
+ params: [ 'path' ],
+ expect: { data: '' },
+ filter: function(s) {
+ return (s || '').split(/\n/).filter(function(ln) {
+ return ln.match(/\S/) && !ln.match(/^nodev\t/);
+ }).map(function(ln) {
+ return ln.trim();
+ });
+ }
+});
+
+callFileStat = rpc.declare({
+ object: 'file',
+ method: 'stat',
+ params: [ 'path' ],
+ expect: { '': {} },
+ filter: function(st) {
+ return (L.isObject(st) && st.path != null);
+ }
+});
+
+callFileExec = rpc.declare({
+ object: 'file',
+ method: 'exec',
+ params: [ 'command', 'params' ],
+ expect: { code: 255 }
+});
+
+function device_textvalue(devices, section_id) {
+ var v = (uci.get('fstab', section_id, 'uuid') || '').toLowerCase(),
+ e = Object.keys(devices).filter(function(dev) { return (devices[dev].uuid || '-').toLowerCase() == v })[0];
+
+ if (v) {
+ this.section.devices[section_id] = devices[e];
+
+ if (e && devices[e].size)
+ return E('span', 'UUID: %h (%s, %1024.2mB)'.format(v, devices[e].dev, devices[e].size));
+ else if (e)
+ return E('span', 'UUID: %h (%s)'.format(v, devices[e].dev));
+ else
+ return E('span', 'UUID: %h (<em>%s</em>)'.format(v, _('not present')));
+ }
+
+ v = uci.get('fstab', section_id, 'label');
+ e = Object.keys(devices).filter(function(dev) { return devices[dev].label == v })[0];
+
+ if (v) {
+ this.section.devices[section_id] = this.section.devices[section_id] || devices[e];
+
+ if (e && devices[e].size)
+ return E('span', 'Label: %h (%s, %1024.2mB)'.format(v, devices[e].dev, devices[e].size));
+ else if (e)
+ return E('span', 'Label: %h (%s)'.format(v, devices[e].dev));
+ else
+ return E('span', 'Label: %h (<em>%s</em>)'.format(v, _('not present')));
+ }
+
+ v = uci.get('fstab', section_id, 'device');
+ e = Object.keys(devices).filter(function(dev) { return devices[dev].dev == v })[0];
+
+ if (v) {
+ this.section.devices[section_id] = this.section.devices[section_id] || devices[e];
+
+ if (e && devices[e].size)
+ return E('span', '%h (%1024.2mB)'.format(v, devices[e].size));
+ else if (e)
+ return E('span', '%h'.format(v));
+ else
+ return E('span', '%h (<em>%s</em>)'.format(v, _('not present')));
+ }
+}
+
+return L.view.extend({
+ handleDetect: function(m, ev) {
+ return callBlockDetect()
+ .then(L.bind(uci.unload, uci, 'fstab'))
+ .then(L.bind(m.render, m));
+ },
+
+ handleMountAll: function(m, ev) {
+ return callFileExec('/sbin/block', ['mount'])
+ .then(function(rc) {
+ if (rc != 0)
+ L.ui.addNotification(null, E('p', _('The <em>block mount</em> command failed with code %d').format(rc)));
+ })
+ .then(L.bind(uci.unload, uci, 'fstab'))
+ .then(L.bind(m.render, m));
+ },
+
+ handleUmount: function(m, path, ev) {
+ return callUmount(path)
+ .then(L.bind(uci.unload, uci, 'fstab'))
+ .then(L.bind(m.render, m));
+ },
+
+ load: function() {
+ return Promise.all([
+ callBlockDevices(),
+ callFileRead('/proc/filesystems'),
+ callFileRead('/etc/filesystems'),
+ callFileStat('/usr/sbin/e2fsck'),
+ callFileStat('/usr/sbin/fsck.f2fs'),
+ callFileStat('/usr/sbin/dosfsck'),
+ callFileStat('/usr/bin/btrfsck')
+ ]);
+ },
+
+ render: function(results) {
+ var devices = results[0],
+ procfs = results[1],
+ etcfs = results[2],
+ triggers = {},
+ trigger, m, s, o;
+
+ var filesystems = procfs.concat(etcfs.filter(function(fs) {
+ return procfs.indexOf(fs) < 0;
+ })).sort();
+
+ var fsck = {
+ ext2: results[3],
+ ext3: results[3],
+ ext4: results[3],
+ f2fs: results[4],
+ vfat: results[5],
+ btrfs: results[6]
+ };
+
+ m = new form.Map('fstab', _('Mount Points'));
+
+ s = m.section(form.TypedSection, 'global', _('Global Settings'));
+ s.addremove = false;
+ s.anonymous = true;
+
+ o = s.option(form.Button, '_detect', _('Generate Config'), _('Find all currently attached filesystems and swap and replace configuration with defaults based on what was detected'));
+ o.onclick = this.handleDetect.bind(this, m);
+ o.inputstyle = 'reload';
+
+ o = s.option(form.Button, '_mountall', _('Mount attached devices'), _('Attempt to enable configured mount points for attached devices'));
+ o.onclick = this.handleMountAll.bind(this, m);
+ o.inputstyle = 'reload';
+
+ o = s.option(form.Flag, 'anon_swap', _('Anonymous Swap'), _('Mount swap not specifically configured'));
+ o.default = o.disabled;
+ o.rmempty = false;
+
+ o = s.option(form.Flag, 'anon_mount', _('Anonymous Mount'), _('Mount filesystems not specifically configured'));
+ o.default = o.disabled;
+ o.rmempty = false;
+
+ o = s.option(form.Flag, 'auto_swap', _('Automount Swap'), _('Automatically mount swap on hotplug'));
+ o.default = o.enabled;
+ o.rmempty = false;
+
+ o = s.option(form.Flag, 'auto_mount', _('Automount Filesystem'), _('Automatically mount filesystems on hotplug'));
+ o.default = o.enabled;
+ o.rmempty = false;
+
+ o = s.option(form.Flag, 'check_fs', _('Check filesystems before mount'), _('Automatically check filesystem for errors before mounting'));
+ o.default = o.disabled;
+ o.rmempty = false;
+
+
+ // Mount status table
+ o = s.option(form.DummyValue, '_mtab');
+
+ o.load = function(section_id) {
+ return callMountPoints().then(L.bind(function(mounts) {
+ this.mounts = mounts;
+ }, this));
+ };
+
+ o.render = L.bind(function(view, section_id) {
+ var table = E('div', { 'class': 'table' }, [
+ E('div', { 'class': 'tr table-titles' }, [
+ E('div', { 'class': 'th' }, _('Filesystem')),
+ E('div', { 'class': 'th' }, _('Mount Point')),
+ E('div', { 'class': 'th center' }, _('Available')),
+ E('div', { 'class': 'th center' }, _('Used')),
+ E('div', { 'class': 'th' }, _('Unmount'))
+ ])
+ ]);
+
+ var rows = [];
+
+ for (var i = 0; i < this.mounts.length; i++) {
+ var used = this.mounts[i].size - this.mounts[i].free,
+ umount = true;
+
+ if (/^\/(overlay|rom|tmp(?:\/.+)?|dev(?:\/.+)?|)$/.test(this.mounts[i].mount))
+ umount = false;
+
+ rows.push([
+ this.mounts[i].device,
+ this.mounts[i].mount,
+ '%1024.2mB / %1024.2mB'.format(this.mounts[i].avail, this.mounts[i].size),
+ '%.2f%% (%1024.2mB)'.format(100 / this.mounts[i].size * used, used),
+ umount ? E('button', {
+ 'class': 'btn cbi-button-remove',
+ 'click': L.ui.createHandlerFn(view, 'handleUmount', m, this.mounts[i].mount)
+ }, [ _('Unmount') ]) : '-'
+ ]);
+ }
+
+ cbi_update_table(table, rows, E('em', _('Unable to obtain mount information')));
+
+ return E([], [ E('h3', _('Mounted file systems')), table ]);
+ }, o, this);
+
+
+ // Mounts
+ s = m.section(form.GridSection, 'mount', _('Mount Points'), _('Mount Points define at which point a memory device will be attached to the filesystem'));
+ s.modaltitle = _('Mount Points - Mount Entry');
+ s.anonymous = true;
+ s.addremove = true;
+ s.sortable = true;
+ s.devices = {};
+
+ s.renderHeaderRows = function(/* ... */) {
+ var trEls = form.GridSection.prototype.renderHeaderRows.apply(this, arguments);
+ return trEls.childNodes[0];
+ }
+
+ s.tab('general', _('General Settings'));
+ s.tab('advanced', _('Advanced Settings'));
+
+ o = s.taboption('general', form.Flag, 'enabled', _('Enabled'));
+ o.rmempty = false;
+ o.editable = true;
+
+ o = s.taboption('general', form.DummyValue, '_device', _('Device'));
+ o.rawhtml = true;
+ o.modalonly = false;
+ o.write = function() {};
+ o.remove = function() {};
+ o.textvalue = device_textvalue.bind(o, devices);
+
+ o = s.taboption('general', form.Value, 'uuid', _('UUID'), _('If specified, mount the device by its UUID instead of a fixed device node'));
+ o.modalonly = true;
+ o.value('', _('-- match by uuid --'));
+
+ var devs = Object.keys(devices).sort();
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.uuid && dev.size)
+ o.value(dev.uuid, '%s (%s, %1024.2mB)'.format(dev.uuid, dev.dev, dev.size));
+ else if (dev.uuid)
+ o.value(dev.uuid, '%s (%s)'.format(dev.uuid, dev.dev));
+ }
+
+ o = s.taboption('general', form.Value, 'label', _('Label'), _('If specified, mount the device by the partition label instead of a fixed device node'));
+ o.modalonly = true;
+ o.depends('uuid', '');
+ o.value('', _('-- match by label --'));
+
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.label && dev.size)
+ o.value(dev.label, '%s (%s, %1024.2mB)'.format(dev.label, dev.dev, dev.size));
+ else if (dev.label)
+ o.value(dev.label, '%s (%s)'.format(dev.label, dev.dev));
+ }
+
+ o = s.taboption('general', form.Value, 'device', _('Device'), _('The device file of the memory or partition (<abbr title="for example">e.g.</abbr> <code>/dev/sda1</code>)'));
+ o.modalonly = true;
+ o.depends({ uuid: '', label: '' });
+
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.size)
+ o.value(dev.dev, '%s (%1024.2mB)'.format(dev.dev, dev.size));
+ else
+ o.value(dev.dev);
+ }
+
+ o = s.taboption('general', form.Value, 'target', _('Mount point'), _('Specifies the directory the device is attached to'));
+ o.value('/', _('Use as root filesystem (/)'));
+ o.value('/overlay', _('Use as external overlay (/overlay)'));
+ o.rmempty = false;
+
+ o = s.taboption('general', form.DummyValue, '__notice', _('Root preparation'));
+ o.depends('target', '/');
+ o.modalonly = true;
+ o.rawhtml = true;
+ o.default = '' +
+ '<p>%s</p>'.format(_('Make sure to clone the root filesystem using something like the commands below:')) +
+ '<pre>' +
+ 'mkdir -p /tmp/introot\n' +
+ 'mkdir -p /tmp/extroot\n' +
+ 'mount --bind / /tmp/introot\n' +
+ 'mount /dev/sda1 /tmp/extroot\n' +
+ 'tar -C /tmp/introot -cvf - . | tar -C /tmp/extroot -xf -\n' +
+ 'umount /tmp/introot\n' +
+ 'umount /tmp/extroot\n' +
+ '</pre>'
+ ;
+
+ o = s.taboption('advanced', form.ListValue, 'fstype', _('Filesystem'));
+
+ o.textvalue = function(section_id) {
+ var dev = this.section.devices[section_id],
+ text = this.cfgvalue(section_id) || 'auto';
+
+ if (dev && dev.type && dev.type != text)
+ text += ' (%s)'.format(dev.type);
+
+ return text;
+ };
+
+ o.value('', 'auto');
+
+ for (var i = 0; i < filesystems.length; i++)
+ o.value(filesystems[i]);
+
+ o = s.taboption('advanced', form.Value, 'options', _('Mount options'), _('See "mount" manpage for details'));
+ o.textvalue = function(section_id) { return this.cfgvalue(section_id) || 'defaults' };
+ o.placeholder = 'defaults';
+
+ s.taboption('advanced', form.Flag, 'enabled_fsck', _('Run filesystem check'), _('Run a filesystem check before mounting the device'));
+
+
+ // Swaps
+ s = m.section(form.GridSection, 'swap', _('SWAP'), _('If your physical memory is insufficient unused data can be temporarily swapped to a swap-device resulting in a higher amount of usable <abbr title="Random Access Memory">RAM</abbr>. Be aware that swapping data is a very slow process as the swap-device cannot be accessed with the high datarates of the <abbr title="Random Access Memory">RAM</abbr>.'));
+ s.modaltitle = _('Mount Points - Swap Entry');
+ s.anonymous = true;
+ s.addremove = true;
+ s.sortable = true;
+ s.devices = {};
+
+ s.renderHeaderRows = function(/* ... */) {
+ var trEls = form.GridSection.prototype.renderHeaderRows.apply(this, arguments);
+ trEls.childNodes[0].childNodes[1].style.width = '90%';
+ return trEls.childNodes[0];
+ }
+
+ o = s.option(form.Flag, 'enabled', _('Enabled'));
+ o.rmempty = false;
+ o.editable = true;
+
+ o = s.option(form.DummyValue, '_device', _('Device'));
+ o.modalonly = false;
+ o.textvalue = device_textvalue.bind(o, devices);
+
+ o = s.option(form.Value, 'uuid', _('UUID'), _('If specified, mount the device by its UUID instead of a fixed device node'));
+ o.modalonly = true;
+ o.value('', _('-- match by uuid --'));
+
+ var devs = Object.keys(devices).sort();
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.dev.match(/^\/dev\/(mtdblock|ubi|ubiblock)\d/))
+ continue;
+
+ if (dev.uuid && dev.size)
+ o.value(dev.uuid, '%s (%s, %1024.2mB)'.format(dev.uuid, dev.dev, dev.size));
+ else if (dev.uuid)
+ o.value(dev.uuid, '%s (%s)'.format(dev.uuid, dev.dev));
+ }
+
+ o = s.option(form.Value, 'label', _('Label'), _('If specified, mount the device by the partition label instead of a fixed device node'));
+ o.modalonly = true;
+ o.depends('uuid', '');
+ o.value('', _('-- match by label --'));
+
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.dev.match(/^\/dev\/(mtdblock|ubi|ubiblock)\d/))
+ continue;
+
+ if (dev.label && dev.size)
+ o.value(dev.label, '%s (%s, %1024.2mB)'.format(dev.label, dev.dev, dev.size));
+ else if (dev.label)
+ o.value(dev.label, '%s (%s)'.format(dev.label, dev.dev));
+ }
+
+ o = s.option(form.Value, 'device', _('Device'), _('The device file of the memory or partition (<abbr title="for example">e.g.</abbr> <code>/dev/sda1</code>)'));
+ o.modalonly = true;
+ o.depends({ uuid: '', label: '' });
+
+ for (var i = 0; i < devs.length; i++) {
+ var dev = devices[devs[i]];
+ if (dev.dev.match(/^\/dev\/(mtdblock|ubi|ubiblock)\d/))
+ continue;
+
+ if (dev.size)
+ o.value(dev.dev, '%s (%1024.2mB)'.format(dev.dev, dev.size));
+ else
+ o.value(dev.dev);
+ }
+
+ return m.render();
+ }
+});
diff --git a/modules/luci-mod-system/luasrc/controller/admin/system.lua b/modules/luci-mod-system/luasrc/controller/admin/system.lua
index 0ce08d10b..eaf1105dd 100644
--- a/modules/luci-mod-system/luasrc/controller/admin/system.lua
+++ b/modules/luci-mod-system/luasrc/controller/admin/system.lua
@@ -23,9 +23,7 @@ function index()
entry({"admin", "system", "crontab"}, view("system/crontab"), _("Scheduled Tasks"), 46)
if fs.access("/sbin/block") and fs.access("/etc/config/fstab") then
- entry({"admin", "system", "fstab"}, cbi("admin_system/fstab"), _("Mount Points"), 50)
- entry({"admin", "system", "fstab", "mount"}, cbi("admin_system/fstab/mount"), nil).leaf = true
- entry({"admin", "system", "fstab", "swap"}, cbi("admin_system/fstab/swap"), nil).leaf = true
+ entry({"admin", "system", "mounts"}, view("system/mounts"), _("Mount Points"), 50)
end
local nodes, number = fs.glob("/sys/class/leds/*")
diff --git a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab.lua b/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab.lua
deleted file mode 100644
index 4a31146a0..000000000
--- a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab.lua
+++ /dev/null
@@ -1,272 +0,0 @@
--- Copyright 2008 Steven Barth <steven@midlink.org>
--- Licensed to the public under the Apache License 2.0.
-
-require("luci.tools.webadmin")
-
-local fs = require "nixio.fs"
-local util = require "nixio.util"
-local tp = require "luci.template.parser"
-
-local block = io.popen("block info", "r")
-local ln, dev, devices = nil, nil, {}
-
-repeat
- ln = block:read("*l")
- dev = ln and ln:match("^/dev/(.-):")
-
- if dev then
- local e, s, key, val = { }
-
- for key, val in ln:gmatch([[(%w+)="(.-)"]]) do
- e[key:lower()] = val
- devices[val] = e
- end
-
- s = tonumber((fs.readfile("/sys/class/block/%s/size" % dev)))
-
- e.dev = "/dev/%s" % dev
- e.size = s and math.floor(s / 2048)
-
- devices[e.dev] = e
- end
-until not ln
-
-block:close()
-
-m = Map("fstab", translate("Mount Points"))
-s = m:section(TypedSection, "global", translate("Global Settings"))
-s.addremove = false
-s.anonymous = true
-
-detect = s:option(Button, "block_detect", translate("Generate Config"), translate("Find all currently attached filesystems and swap and replace configuration with defaults based on what was detected"))
-detect.inputstyle = "reload"
-
-detect.write = function(self, section)
- luci.sys.call("block detect >/etc/config/fstab")
- luci.http.redirect(luci.dispatcher.build_url("admin/system", "fstab"))
-end
-
-o = s:option(Flag, "anon_swap", translate("Anonymous Swap"), translate("Mount swap not specifically configured"))
-o.default = o.disabled
-o.rmempty = false
-
-o = s:option(Flag, "anon_mount", translate("Anonymous Mount"), translate("Mount filesystems not specifically configured"))
-o.default = o.disabled
-o.rmempty = false
-
-o = s:option(Flag, "auto_swap", translate("Automount Swap"), translate("Automatically mount swap on hotplug"))
-o.default = o.enabled
-o.rmempty = false
-
-o = s:option(Flag, "auto_mount", translate("Automount Filesystem"), translate("Automatically mount filesystems on hotplug"))
-o.default = o.enabled
-o.rmempty = false
-
-o = s:option(Flag, "check_fs", translate("Check filesystems before mount"), translate("Automatically check filesystem for errors before mounting"))
-o.default = o.disabled
-o.rmempty = false
-
-local mounts = luci.sys.mounts()
-local non_system_mounts = {}
-for rawmount, val in pairs(mounts) do
- if (string.find(val.mountpoint, "/tmp/.jail") == nil) then
- repeat
- val.umount = false
- if (val.mountpoint == "/") then
- break
- elseif (val.mountpoint == "/overlay") then
- break
- elseif (val.mountpoint == "/rom") then
- break
- elseif (val.mountpoint == "/tmp") then
- break
- elseif (val.mountpoint == "/tmp/shm") then
- break
- elseif (val.mountpoint == "/tmp/upgrade") then
- break
- elseif (val.mountpoint == "/dev") then
- break
- end
- val.umount = true
- until true
- non_system_mounts[rawmount] = val
- end
-end
-
-v = m:section(Table, non_system_mounts, translate("Mounted file systems"))
-
-fs = v:option(DummyValue, "fs", translate("Filesystem"))
-
-mp = v:option(DummyValue, "mountpoint", translate("Mount Point"))
-
-avail = v:option(DummyValue, "avail", translate("Available"))
-function avail.cfgvalue(self, section)
- return luci.tools.webadmin.byte_format(
- ( tonumber(mounts[section].available) or 0 ) * 1024
- ) .. " / " .. luci.tools.webadmin.byte_format(
- ( tonumber(mounts[section].blocks) or 0 ) * 1024
- )
-end
-
-used = v:option(DummyValue, "used", translate("Used"))
-function used.cfgvalue(self, section)
- return ( mounts[section].percent or "0%" ) .. " (" ..
- luci.tools.webadmin.byte_format(
- ( tonumber(mounts[section].used) or 0 ) * 1024
- ) .. ")"
-end
-
-unmount = v:option(Button, "unmount", translate("Unmount"))
-function unmount.cfgvalue(self, section)
- return non_system_mounts[section].umount
-end
-
-unmount.render = function(self, section, scope)
- self.title = translate("Unmount")
- self.inputstyle = "remove"
- Button.render(self, section, scope)
-end
-
-unmount.write = function(self, section)
- if non_system_mounts[section].umount then
- luci.sys.call("/bin/umount '%s'" % luci.util.shellstartsqescape(non_system_mounts[section].mountpoint))
- return luci.http.redirect(luci.dispatcher.build_url("admin/system", "fstab"))
- end
-end
-
-mount = m:section(TypedSection, "mount", translate("Mount Points"), translate("Mount Points define at which point a memory device will be attached to the filesystem"))
-mount.anonymous = true
-mount.addremove = true
-mount.template = "cbi/tblsection"
-mount.extedit = luci.dispatcher.build_url("admin/system/fstab/mount/%s")
-
-mount.create = function(...)
- local sid = TypedSection.create(...)
- if sid then
- luci.http.redirect(mount.extedit % sid)
- return
- end
-end
-
-
-mount:option(Flag, "enabled", translate("Enabled")).rmempty = false
-
-dev = mount:option(DummyValue, "device", translate("Device"))
-dev.rawhtml = true
-dev.cfgvalue = function(self, section)
- local v, e
-
- v = m.uci:get("fstab", section, "uuid")
- e = v and devices[v:lower()]
- if v and e and e.size then
- return "UUID: %s (%s, %d MB)" %{ tp.pcdata(v), e.dev, e.size }
- elseif v and e then
- return "UUID: %s (%s)" %{ tp.pcdata(v), e.dev }
- elseif v then
- return "UUID: %s (<em>%s</em>)" %{ tp.pcdata(v), translate("not present") }
- end
-
- v = m.uci:get("fstab", section, "label")
- e = v and devices[v]
- if v and e and e.size then
- return "Label: %s (%s, %d MB)" %{ tp.pcdata(v), e.dev, e.size }
- elseif v and e then
- return "Label: %s (%s)" %{ tp.pcdata(v), e.dev }
- elseif v then
- return "Label: %s (<em>%s</em>)" %{ tp.pcdata(v), translate("not present") }
- end
-
- v = Value.cfgvalue(self, section) or "?"
- e = v and devices[v]
- if v and e and e.size then
- return "%s (%d MB)" %{ tp.pcdata(v), e.size }
- elseif v and e then
- return tp.pcdata(v)
- elseif v then
- return "%s (<em>%s</em>)" %{ tp.pcdata(v), translate("not present") }
- end
-end
-
-mp = mount:option(DummyValue, "target", translate("Mount Point"))
-mp.cfgvalue = function(self, section)
- if m.uci:get("fstab", section, "is_rootfs") == "1" then
- return "/overlay"
- else
- return Value.cfgvalue(self, section) or "?"
- end
-end
-
-fs = mount:option(DummyValue, "fstype", translate("Filesystem"))
-fs.cfgvalue = function(self, section)
- local v, e
-
- v = m.uci:get("fstab", section, "uuid")
- v = v and v:lower() or m.uci:get("fstab", section, "label")
- v = v or m.uci:get("fstab", section, "device")
-
- e = v and devices[v]
-
- return e and e.type or m.uci:get("fstab", section, "fstype") or "?"
-end
-
-op = mount:option(DummyValue, "options", translate("Options"))
-op.cfgvalue = function(self, section)
- return Value.cfgvalue(self, section) or "defaults"
-end
-
-rf = mount:option(DummyValue, "is_rootfs", translate("Root"))
-rf.cfgvalue = function(self, section)
- local target = m.uci:get("fstab", section, "target")
- if target == "/" then
- return translate("yes")
- elseif target == "/overlay" then
- return translate("overlay")
- else
- return translate("no")
- end
-end
-
-ck = mount:option(DummyValue, "enabled_fsck", translate("Check"))
-ck.cfgvalue = function(self, section)
- return Value.cfgvalue(self, section) == "1"
- and translate("yes") or translate("no")
-end
-
-
-swap = m:section(TypedSection, "swap", translate("SWAP"), translate("If your physical memory is insufficient unused data can be temporarily swapped to a swap-device resulting in a higher amount of usable <abbr title=\"Random Access Memory\">RAM</abbr>. Be aware that swapping data is a very slow process as the swap-device cannot be accessed with the high datarates of the <abbr title=\"Random Access Memory\">RAM</abbr>."))
-swap.anonymous = true
-swap.addremove = true
-swap.template = "cbi/tblsection"
-swap.extedit = luci.dispatcher.build_url("admin/system/fstab/swap/%s")
-
-swap.create = function(...)
- local sid = TypedSection.create(...)
- if sid then
- luci.http.redirect(swap.extedit % sid)
- return
- end
-end
-
-
-swap:option(Flag, "enabled", translate("Enabled")).rmempty = false
-
-dev = swap:option(DummyValue, "device", translate("Device"))
-dev.cfgvalue = function(self, section)
- local v
-
- v = m.uci:get("fstab", section, "uuid")
- if v then return "UUID: %s" % v end
-
- v = m.uci:get("fstab", section, "label")
- if v then return "Label: %s" % v end
-
- v = Value.cfgvalue(self, section) or "?"
- e = v and devices[v]
- if v and e and e.size then
- return "%s (%s MB)" % {v, e.size}
- else
- return v
- end
-end
-
-return m
diff --git a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/mount.lua b/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/mount.lua
deleted file mode 100644
index f21a2775e..000000000
--- a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/mount.lua
+++ /dev/null
@@ -1,158 +0,0 @@
--- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
--- Licensed to the public under the Apache License 2.0.
-
-local fs = require "nixio.fs"
-local util = require "nixio.util"
-
-local has_fscheck = fs.access("/usr/sbin/e2fsck")
-
-local block = io.popen("block info", "r")
-local ln, dev, devices = nil, nil, {}
-
-repeat
- ln = block:read("*l")
- dev = ln and ln:match("^/dev/(.-):")
-
- if dev then
- local e, s, key, val = { }
-
- for key, val in ln:gmatch([[(%w+)="(.-)"]]) do
- e[key:lower()] = val
- end
-
- s = tonumber((fs.readfile("/sys/class/block/%s/size" % dev)))
-
- e.dev = "/dev/%s" % dev
- e.size = s and math.floor(s / 2048)
-
- devices[#devices+1] = e
- end
-until not ln
-
-block:close()
-
-
-m = Map("fstab", translate("Mount Points - Mount Entry"))
-m.redirect = luci.dispatcher.build_url("admin/system/fstab")
-
-if not arg[1] or m.uci:get("fstab", arg[1]) ~= "mount" then
- luci.http.redirect(m.redirect)
- return
-end
-
-
-
-mount = m:section(NamedSection, arg[1], "mount", translate("Mount Entry"))
-mount.anonymous = true
-mount.addremove = false
-
-mount:tab("general", translate("General Settings"))
-mount:tab("advanced", translate("Advanced Settings"))
-
-
-mount:taboption("general", Flag, "enabled", translate("Enable this mount")).rmempty = false
-
-
-o = mount:taboption("general", Value, "uuid", translate("UUID"),
- translate("If specified, mount the device by its UUID instead of a fixed device node"))
-
-o:value("", translate("-- match by uuid --"))
-
-for i, d in ipairs(devices) do
- if d.uuid and d.size then
- o:value(d.uuid, "%s (%s, %d MB)" %{ d.uuid, d.dev, d.size })
- elseif d.uuid then
- o:value(d.uuid, "%s (%s)" %{ d.uuid, d.dev })
- end
-end
-
-
-o = mount:taboption("general", Value, "label", translate("Label"),
- translate("If specified, mount the device by the partition label instead of a fixed device node"))
-
-o:value("", translate("-- match by label --"))
-
-o:depends("uuid", "")
-
-for i, d in ipairs(devices) do
- if d.label and d.size then
- o:value(d.label, "%s (%s, %d MB)" %{ d.label, d.dev, d.size })
- elseif d.label then
- o:value(d.label, "%s (%s)" %{ d.label, d.dev })
- end
-end
-
-
-o = mount:taboption("general", Value, "device", translate("Device"),
- translate("The device file of the memory or partition (<abbr title=\"for example\">e.g.</abbr> <code>/dev/sda1</code>)"))
-
-o:value("", translate("-- match by device --"))
-
-o:depends({ uuid = "", label = "" })
-
-for i, d in ipairs(devices) do
- if d.size then
- o:value(d.dev, "%s (%d MB)" %{ d.dev, d.size })
- else
- o:value(d.dev)
- end
-end
-
-
-o = mount:taboption("general", Value, "target", translate("Mount point"),
- translate("Specifies the directory the device is attached to"))
-
-o:value("/", translate("Use as root filesystem (/)"))
-o:value("/overlay", translate("Use as external overlay (/overlay)"))
-
-
-o = mount:taboption("general", DummyValue, "__notice", translate("Root preparation"))
-o:depends("target", "/")
-o.rawhtml = true
-o.default = [[
-<p>%s</p><pre>mkdir -p /tmp/introot
-mkdir -p /tmp/extroot
-mount --bind / /tmp/introot
-mount /dev/sda1 /tmp/extroot
-tar -C /tmp/introot -cvf - . | tar -C /tmp/extroot -xf -
-umount /tmp/introot
-umount /tmp/extroot</pre>
-]] %{
- translate("Make sure to clone the root filesystem using something like the commands below:"),
-
-}
-
-
-o = mount:taboption("advanced", Value, "fstype", translate("Filesystem"),
- translate("The filesystem that was used to format the memory (<abbr title=\"for example\">e.g.</abbr> <samp><abbr title=\"Third Extended Filesystem\">ext3</abbr></samp>)"))
-
-o:value("", "auto")
-
-local fs
-for fs in io.lines("/proc/filesystems") do
- fs = fs:match("%S+")
- if fs ~= "nodev" then
- o:value(fs)
- end
-end
-
-local ok, lines = pcall(io.lines, "/etc/filesystem")
-if ok then
- local fs
- for fs in lines do
- o:value(fs)
- end
-end
-
-o = mount:taboption("advanced", Value, "options", translate("Mount options"),
- translate("See \"mount\" manpage for details"))
-
-o.placeholder = "defaults"
-
-
-if has_fscheck then
- o = mount:taboption("advanced", Flag, "enabled_fsck", translate("Run filesystem check"),
- translate("Run a filesystem check before mounting the device"))
-end
-
-return m
diff --git a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/swap.lua b/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/swap.lua
deleted file mode 100644
index 82468d5fc..000000000
--- a/modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab/swap.lua
+++ /dev/null
@@ -1,54 +0,0 @@
--- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
--- Licensed to the public under the Apache License 2.0.
-
-local fs = require "nixio.fs"
-local util = require "nixio.util"
-
-local devices = {}
-util.consume((fs.glob("/dev/sd*")), devices)
-util.consume((fs.glob("/dev/hd*")), devices)
-util.consume((fs.glob("/dev/scd*")), devices)
-util.consume((fs.glob("/dev/mmc*")), devices)
-
-local size = {}
-for i, dev in ipairs(devices) do
- local s = tonumber((fs.readfile("/sys/class/block/%s/size" % dev:sub(6))))
- size[dev] = s and math.floor(s / 2048)
-end
-
-
-m = Map("fstab", translate("Mount Points - Swap Entry"))
-m.redirect = luci.dispatcher.build_url("admin/system/fstab")
-
-if not arg[1] or m.uci:get("fstab", arg[1]) ~= "swap" then
- luci.http.redirect(m.redirect)
- return
-end
-
-
-mount = m:section(NamedSection, arg[1], "swap", translate("Swap Entry"))
-mount.anonymous = true
-mount.addremove = false
-
-mount:tab("general", translate("General Settings"))
-mount:tab("advanced", translate("Advanced Settings"))
-
-
-mount:taboption("general", Flag, "enabled", translate("Enable this swap")).rmempty = false
-
-
-o = mount:taboption("general", Value, "device", translate("Device"),
- translate("The device file of the memory or partition (<abbr title=\"for example\">e.g.</abbr> <code>/dev/sda1</code>)"))
-
-for i, d in ipairs(devices) do
- o:value(d, size[d] and "%s (%s MB)" % {d, size[d]})
-end
-
-o = mount:taboption("advanced", Value, "uuid", translate("UUID"),
- translate("If specified, mount the device by its UUID instead of a fixed device node"))
-
-o = mount:taboption("advanced", Value, "label", translate("Label"),
- translate("If specified, mount the device by the partition label instead of a fixed device node"))
-
-
-return m