ACC SHELL
/**
* File: StorageFields.ycp
* Package: yast2-storage
* Summary: Expert Partitioner
* Authors: Arvin Schnell <aschnell@suse.de>
*/
{
module "StorageFields";
textdomain "storage";
import "Storage";
import "StorageIcons";
import "FileSystems";
import "Partitions";
import "Directory";
import "Mode";
import "HTML";
import "Integer";
import "String";
import "Region";
/**
* Call callback for every disk of target_map in a well defined sorted order.
*/
global void IterateTargetMap(map<string, map> target_map, void(map<string, map>, map) callback)
{
const map disk_order = $[ `CT_DMRAID : 0, `CT_DMMULTIPATH : 1, `CT_MDPART : 2, `CT_DISK : 3,
`CT_MD : 4, `CT_LOOP : 5, `CT_LVM : 6, `CT_DM : 7, `CT_NFS : 8 ];
list<string> keys = maplist(string dev, map disk, target_map, { return dev; });
keys = sort(string a, string b, keys, {
integer oa = disk_order[target_map[a, "type"]:`CT_UNKNOWN]:9;
integer ob = disk_order[target_map[b, "type"]:`CT_UNKNOWN]:9;
return (oa==ob) ? (a<b) : (oa<ob);
});
foreach(string dev, keys, {
map disk = target_map[dev]:$[];
callback(target_map, disk);
});
};
string BooleanToHumanString(boolean value)
{
if (value)
// human text for Boolean value
return _("Yes");
else
// human text for Boolean value
return _("No");
}
string UsedByString(map<string, any> used_by)
{
symbol type = used_by["type"]:`UB_NONE;
string device = used_by["device"]:"";
switch (type)
{
case `UB_LVM:
return "LVM " + device;
case `UB_DM:
return "DM " + device;
case `UB_DMRAID:
return "DM RAID " + device;
case `UB_DMMULTIPATH:
return "DM Multipath " + device;
case `UB_MD:
case `UB_MDPART:
return "MD RAID " + device;
default:
return device;
}
}
global term TableHeader(list<symbol> fields)
{
term header = `header();
foreach(symbol field, fields, {
switch (field)
{
case `device:
// Column header
header = add(header, _("Device"));
break;
case `size:
// Column header
header = add(header, `Right(_("Size")));
break;
case `type:
// Column header
header = add(header, _("Type"));
break;
case `format:
// Column header, abbreviation for "format" (to format a partition)
header = add(header, `Center(_("F")));
break;
case `encrypted:
// Column header, , abbreviation for "encrypted" (an encrypted device)
header = add(header, `Center(_("Enc")));
break;
case `fs_type:
// Column header, abbreviation for "Filesystem Type"
header = add(header, _("FS Type"));
break;
case `mount_point:
// Column header
header = add(header, _("Mount Point"));
break;
case `mount_by:
// Column header
header = add(header, _("Mount By"));
break;
case `used_by:
// Column header
header = add(header, _("Used By"));
break;
case `start_cyl:
// Column header
header = add(header, `Right(_("Start")));
break;
case `end_cyl:
// Column header
header = add(header, `Right(_("End")));
break;
case `fs_id:
// Column header
header = add(header, `Right(_("FS Id")));
break;
case `uuid:
// Column header
header = add(header, _("UUID"));
break;
case `label:
// Column header
header = add(header, _("Label"));
break;
case `udev_path:
// Column header
header = add(header, _("Device Path"));
break;
case `udev_id:
// Column header
header = add(header, _("Device ID"));
break;
case `bios_id:
// Column header
header = add(header, _("BIOS ID"));
break;
case `disk_label:
// Column header
header = add(header, _("Disk Label"));
break;
case `lvm_metadata:
// Column header
header = add(header, _("Metadata"));
break;
case `pe_size:
// Column header, abbreviation for "Physical Extent"
header = add(header, _("PE Size"));
break;
case `stripes:
// Column header
header = add(header, _("Stripes"));
break;
case `raid_version:
// Column header
header = add(header, _("RAID Version"));
break;
case `raid_type:
// Column header
header = add(header, _("RAID Type"));
break;
case `chunk_size:
// Column header
header = add(header, _("Chunk Size"));
break;
case `parity_algorithm:
// Column header
header = add(header, _("Parity Algorithm"));
break;
default:
y2error("unknown field %1", field);
header = add(header, "error");
break;
}
});
return header;
}
string Helptext(symbol field, symbol style)
{
string ret = "<p>";
switch (field)
{
case `bios_id:
// helptext for table column and overview entry
ret = ret + _("<b>BIOS ID</b> shows the BIOS ID of the hard
disk. This field can be empty.");
break;
case `bus:
// helptext for table column and overview entry
ret = ret + _("<b>Bus</b> shows how the device is connected to
the system. This field can be empty, e.g. for multipath disks.");
break;
case `chunk_size:
// helptext for table column and overview entry
ret = ret + _("<b>Chunk Size</b> shows the chunk size for RAID
devices.");
break;
case `cyl_size:
// helptext for table column and overview entry
ret = ret + _("<b>Cylinder Size</b> shows the size of the
cylinders of the hard disk.");
break;
case `sector_size:
// helptext for table column and overview entry
ret = ret + _("<b>Sector Size</b> shows the size of the
sectors of the hard disk.");
break;
case `device:
// helptext for table column and overview entry
ret = ret + _("<b>Device</b> shows the kernel name of the
device.");
break;
case `disk_label:
// helptext for table column and overview entry
ret = ret + _("<b>Disk Label</b> shows the partition table
type of the disk, e.g <tt>MSDOS</tt> or <tt>GPT</tt>.");
break;
case `encrypted:
// helptext for table column and overview entry
ret = ret + _("<b>Encrypted</b> shows whether the device is
encrypted.");
break;
case `end_cyl:
// helptext for table column and overview entry
ret = ret + _("<b>End Cylinder</b> shows the end cylinder of
the partition.");
break;
case `fc_fcp_lun:
// helptext for table column and overview entry
ret = ret + _("<b>LUN</b> shows the Logical Unit Number for
Fibre Channel disks.");
break;
case `fc_port_id:
// helptext for table column and overview entry
ret = ret + _("<b>Port ID</b> shows the port id for Fibre
Channel disks.");
break;
case `fc_wwpn:
// helptext for table column and overview entry
ret = ret + _("<b>WWPN</b> shows the World Wide Port Name for
Fibre Channel disks.");
break;
case `file_path:
// helptext for table column and overview entry
ret = ret + _("<b>File Path</b> shows the path of the file for
an encrypted loop device.");
break;
case `format:
// helptext for table column and overview entry
ret = ret + _("<b>Format</b> shows some flags: <tt>F</tt>
means the device is selected to be formatted.");
break;
case `fs_id:
// helptext for table column and overview entry
ret = ret + _("<b>FS Id</b> shows the file system id.");
break;
case `fs_type:
// helptext for table column and overview entry
ret = ret + _("<b>FS Type</b> shows the file system type.");
break;
case `label:
// helptext for table column and overview entry
ret = ret + _("<b>Label</b> shows the label of the file
system.");
break;
case `lvm_metadata:
// helptext for table column and overview entry
ret = ret + _("<b>Metadata</b> shows the LVM metadata type for
volume groups.");
break;
case `model:
// helptext for table column and overview entry
ret = ret + _("<b>Model</b> shows the device model.");
break;
case `mount_by:
// helptext for table column and overview entry
ret = ret + _("<b>Mount By</b> indicates how the file system
is mounted: (Kernel) by Kernel Name, (Label) by File System Label, (UUID) by
File System UUID, (ID) by Device ID, and (Path) by Device Path.");
if (Mode::normal())
// helptext for table column and overview entry
ret = ret + " " + _("A question mark (?) indicates that
the file system is not listed in <tt>/etc/fstab</tt>. It is either mounted
manually or by some automount system. When changing setting of this volume
YaST will not update <tt>/etc/fstab</tt>.");
break;
case `mount_point:
// helptext for table column and overview entry
ret = ret + _("<b>Mount Point</b> shows where the file system
is mounted.");
if (Mode::normal())
// helptext for table column and overview entry
ret = ret + " " + _("An asterisk (*) after the mount point
indicates a file system that is currently not mounted (for example, because it
has the <tt>noauto</tt> option set in <tt>/etc/fstab</tt>).");
break;
case `num_cyl:
// helptext for table column and overview entry
ret = ret + _("<b>Number of Cylinders</b> shows how many
cylinders the hard disk has.");
break;
case `parity_algorithm:
// helptext for table column and overview entry
ret = ret + _("<b>Parity Algorithm</b> shows the parity
algorithm for RAID devices with RAID type 5.");
break;
case `pe_size:
// helptext for table column and overview entry
ret = ret + _("<b>PE Size</b> shows the physical extent size
for LVM volume groups.");
break;
case `raid_version:
// helptext for table column and overview entry
ret = ret + _("<b>RAID Version</b> shows the RAID version.");
break;
case `raid_type:
// helptext for table column and overview entry
ret = ret + _("<b>RAID Type</b> shows the RAID type, also
called RAID level, for RAID devices.");
break;
case `size:
// helptext for table column and overview entry
ret = ret + _("<b>Size</b> shows the size of the device.");
break;
case `start_cyl:
// helptext for table column and overview entry
ret = ret + _("<b>Start Cylinder</b> shows the start cylinder
of the partition.");
break;
case `stripes:
// helptext for table column and overview entry
ret = ret + _("<b>Stripes</b> shows the stripe number for LVM
logical volumes and, if greater than one, in parenthesise the stripe size.");
break;
case `type:
// helptext for table column and overview entry
ret = ret + _("<b>Type</b> gives a general overview about the
device type.");
break;
case `udev_id:
// helptext for table column and overview entry
ret = ret + _("<b>Device Id</b> shows the persistent device
ids. This field can be empty.");
break;
case `udev_path:
// helptext for table column and overview entry
ret = ret + _("<b>Device Path</b> shows the persistent device
path. This field can be empty.");
break;
case `used_by:
// helptext for table column and overview entry
ret = ret + _("<b>Used By</b> shows if a device is used by
e.g. RAID or LVM. If you do not use such things, it is perfectly normal for
this column to be empty.");
break;
case `uuid:
// helptext for table column and overview entry
ret = ret + _("<b>UUID</b> shows the Universally Unique
Identifier of the file system.");
break;
case `vendor:
// helptext for table column and overview entry
ret = ret + _("<b>Vendor</b> shows the device vendor.");
break;
default:
y2error("unknown field %1", field);
ret = ret + "error";
break;
}
ret = ret + "</p>";
return ret;
}
any MakeSubInfo(map disk, map part, symbol field, symbol style)
{
map data = (part == nil ? disk : part);
symbol type = ( part == nil ? disk["type"]:`primary : part["type"]:`CT_DISK );
string device = data["device"]:"";
switch (field)
{
case `device:
{
string value = device;
if (style == `table)
return value;
else
// row label, %1 is replace by device name
return sformat(_("Device: %1"), String::EscapeTags(value));
}
case `size:
{
string value = Storage::KByteToHumanString(data["size_k"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by size
return sformat(_("Size: %1"), value);
}
case `type:
{
string value = "";
if (part == nil)
{
string disk_device = disk["device"]:"";
string vendor = disk["vendor"]:"";
string model = disk["model"]:"";
if ((model != "") && (vendor != ""))
value = vendor + "-" + model;
else
value = vendor + model;
if (value == "")
{
if (disk["bus"]:"" == "RAID")
{
value = "RAID " + disk_device;
}
else if (disk["type"]:`CT_UNKNOWN == `CT_LVM)
{
value = "LVM" + (disk["lvm2"]:false ? "2 " : " ") + disk["name"]:"";
}
else if (disk["type"]:`CT_UNKNOWN == `CT_DMRAID)
{
value = "DM RAID " + disk["name"]:"";
}
else if (disk["type"]:`CT_UNKNOWN == `CT_DMMULTIPATH)
{
value = "DM Multipath " + disk["name"]:"";
}
else if (disk["type"]:`CT_UNKNOWN == `CT_MDPART)
{
value = "MD RAID " + disk["name"]:"";
}
else
{
// label text
vendor = sformat(_("DISK %1"), substring(disk_device, 5));
}
}
}
else
{
value = part["fstype"]:"";
}
if (style == `table)
return `cell(`icon(Directory::icondir + "22x22/apps/" + StorageIcons::IconMap(type)), value);
else
// row label
return sformat(_("Type: %1"), String::EscapeTags(value));
}
case `format:
{
string value = "";
if (part == nil) {
if (disk["dasdfmt"]:false)
value = value + "X";
} else {
if (part["format"]:false)
value = value + "F";
}
if (style == `table)
return value;
else
// row label
return sformat(_("Format: %1"), value);
}
case `encrypted:
{
boolean value = data["enc_type"]:`none != `none;
if (style == `table)
{
if (value)
{
if (UI::GetDisplayInfo()["HasIconSupport"]:false)
return `cell(`icon(Directory::icondir + "22x22/apps/" + StorageIcons::encrypted_icon), "");
else
return "E";
}
else
return "";
}
else
{
// row label, %1 is replace by "Yes" or "No"
return sformat(_("Encrypted: %1"), BooleanToHumanString(value));
}
}
case `fs_type:
{
string value = FileSystems::GetName(data["used_fs"]:`unknown, "");
if (style == `table)
return value;
else
// row label, %1 is replace by file system name e.g. "Ext3"
return sformat(_("File System: %1"), value);
}
case `mount_point:
{
string value = data["mount"]:"";
if (Mode::normal())
{
if (data["inactive"]:false )
value = value + " *";
}
if (style == `table)
return value;
else
// row label, %1 is replace by mount point e.g. "/mnt"
return sformat(_("Mount Point: %1"), String::EscapeTags(value));
}
case `mount_by:
{
string value = "";
if (data["mount"]:"" != "") {
map tmp = $[ `device : "Kernel", `uuid : "UUID", `label : "Label", `id : "ID", `path : "Path" ];
symbol mount_by = data["mountby"]:`device;
value = tmp[mount_by]:"";
}
if (Mode::normal())
{
boolean tmp = false;
if (Storage::GetIgnoreFstab(device, tmp) && tmp)
value = "?";
}
if (style == `table)
return value;
else
// row label, %1 is replace by mount by method
return sformat(_("Mount By: %1"), value);
}
case `used_by:
{
if (style == `table)
return UsedByString(data["used_by", 0]:$[]);
else
{
integer n = size(data["used_by"]:[]);
return mergestring(maplist(integer i, Integer::Range(n == 0 ? 1 : n), {
// row label, %1 is replaced by number, %2 is replace by device name e.g. /dev/system
return sformat(_("Used By %1: %2"), i+1, String::EscapeTags(UsedByString(data["used_by", i]:$[])));
}), HTML::Newline());
}
}
case `uuid:
{
string value = data["uuid"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by file system uuid
return sformat(_("UUID: %1"), value);
}
case `label:
{
string value = (part == nil) ? "" : data["label"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by file system label
return sformat(_("Label: %1"), String::EscapeTags(value));
}
case `udev_path:
{
string value = data["udev_path"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by udev device path
return sformat(_("Device Path: %1"), value);
}
case `udev_id:
{
if (style == `table) {
return data["udev_id", 0]:"";
} else {
integer n = size(data["udev_id"]:[]);
return mergestring(maplist(integer i, Integer::Range(n == 0 ? 1 : n), {
// row label, %1 is replaced by number, %2 is replace by udef device id
return sformat(_("Device ID %1: %2"), i+1, data["udev_id", i]:"");
}), HTML::Newline());
}
}
case `bios_id:
{
string value = data["bios_id"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by bios id
return sformat(_("BIOS ID: %1"), value);
}
case `disk_label:
{
string value = (part == nil) ? toupper(data["label"]:"") : "";
if (style == `table)
return value;
else
// row label, %1 is replace by disk label e.g. "MSDOS" or "GPT"
return sformat(_("Disk Label: %1"), value);
}
case `vendor:
{
string value = data["vendor"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by vendor name
return sformat(_("Vendor: %1"), String::EscapeTags(value));
}
case `model:
{
string value = data["model"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by model string
return sformat(_("Model: %1"), String::EscapeTags(value));
}
case `bus:
{
string value = data["bus"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by bus name e.g. "SCSI"
return sformat(_("Bus: %1"), value);
}
case `lvm_metadata:
{
string value = "";
if (disk["type"]:`CT_UNKNOWN == `CT_LVM && part == nil)
value = disk["lvm2"]:true ? "LVM2" : "LVM1";
if (style == `table)
return value;
else
// row label, %1 is replace by metadata version string
return sformat(_("Metadata: %1"), value);
}
case `pe_size:
{
string value = "";
if (disk["type"]:`CT_UNKNOWN == `CT_LVM && part == nil)
value = Storage::ByteToHumanStringOmitZeroes(disk["pesize"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by size
return sformat(_("PE Size: %1"), value);
}
case `stripes:
{
string value = "";
if (disk["type"]:`CT_UNKNOWN == `CT_LVM && part != nil)
{
integer stripes = data["stripes"]:1;
integer stripesize = data["stripesize"]:0;
if (stripes == 1)
value = sformat("%1", stripes);
else
value = sformat("%1 (%2)", stripes, Storage::KByteToHumanStringOmitZeroes(stripesize));
}
if (style == `table)
return value;
else
// row label, %1 is replace by integer
return sformat(_("Stripes: %1"), value);
}
case `raid_version:
{
string value = data["sb_ver"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by raid version e.g. "1.00"
return sformat(_("RAID Version: %1"), value);
}
case `raid_type:
{
string value = toupper(data["raid_type"]:"");
if (style == `table)
return value;
else
// row label, %1 is replace by raid type e.g. "RAID1"
return sformat(_("RAID Type: %1"), value);
}
case `chunk_size:
{
string value = "";
if (contains(["raid0", "raid5"], data["raid_type"]:"")) {
integer chunksize = data["chunk_size"]:0;
value = Storage::KByteToHumanStringOmitZeroes(chunksize);
}
if (style == `table)
return value;
else
// row label, %1 is replace by size
return sformat(_("Chunk Size: %1"), value);
}
case `parity_algorithm:
{
string value = "";
if (contains(["raid5"], data["raid_type"]:"")) {
value = data["parity_algorithm"]:"";
value = mergestring(splitstring(value, "_"), "-");
}
if (style == `table)
return value;
else
// row label, %1 is replace by algorithm name
return sformat(_("Parity Algorithm: %1"), value);
}
case `num_cyl:
{
string value = "";
if (part == nil && Storage::IsPartitionable(disk))
value = tostring(disk["cyl_count"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by integer
return sformat(_("Number of Cylinders: %1"), value);
}
case `cyl_size:
{
string value = "";
if (part == nil && Storage::IsPartitionable(disk))
value = Storage::ByteToHumanString(disk["cyl_size"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by size
return sformat(_("Cylinder Size: %1"), value);
}
case `start_cyl:
{
string value = "";
if (Storage::IsPartitionable(disk)) {
if (part == nil)
value = tostring(0);
else
value = tostring(Region::Start(part["region"]:[]));
}
if (style == `table)
return value;
else
// row label, %1 is replace by integer
return sformat(_("Start Cylinder: %1"), value);
}
case `end_cyl:
{
string value = "";
if (Storage::IsPartitionable(disk)) {
if (part == nil)
value = tostring(disk["cyl_count"]:0 - 1);
else
value = tostring(Region::End(part["region"]:[]));
}
if (style == `table)
return value;
else
// row label, %1 is replace by integer
return sformat(_("End Cylinder: %1"), value);
}
case `sector_size:
{
string value = "";
if (part == nil && Storage::IsPartitionable(disk))
value = Storage::ByteToHumanStringOmitZeroes(disk["sector_size"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by size
return sformat(_("Sector Size: %1"), value);
}
case `fs_id:
{
integer fs_id = data["fsid"]:0;
string value = Partitions::ToHexString(fs_id) + " " + Partitions::FsIdToString(fs_id);
if (style == `table)
return value;
else
// row label, %1 is replace by file system id
return sformat(_("FS Id: %1"), value);
}
case `file_path:
{
string value = data["fpath"]:"";
if (style == `table)
return value;
else
// row label, %1 is replace by file path e.g. "/data/secret"
return sformat(_("File Path: %1"), String::EscapeTags(value));
}
case `fc_wwpn:
{
string value = "";
if (haskey(data["fc"]:$[], "wwpn"))
value = "0x" + toupper(substring(tohexstring(data["fc", "wwpn"]:0, 16), 2));
if (style == `table)
return value;
else
// row label, %1 is replace by wwpn
return sformat(_("WWPN: %1"), value);
}
case `fc_fcp_lun:
{
string value = "";
if (haskey(data["fc"]:$[], "fcp_lun"))
value = tostring(data["fc", "fcp_lun"]:0);
if (style == `table)
return value;
else
// row label, %1 is replace by lun
return sformat(_("LUN: %1"), value);
}
case `fc_port_id:
{
string value = "";
if (haskey(data["fc"]:$[], "port_id"))
value = "0x" + toupper(substring(tohexstring(data["fc", "port_id"]:0, 6), 2));
if (style == `table)
return value;
else
// row label, %1 is replace by port id
return sformat(_("Port ID: %1"), value);
}
default:
{
y2error("unknown field %1", field);
return "error";
}
}
}
term TableRow(list<symbol> fields, map disk, map part)
{
string device = (part == nil) ? disk["device"]:"" : part["device"]:"";
term row = list::reduce(term tmp, symbol field, `item(`id(device)), fields, {
return add(tmp, MakeSubInfo(disk, part, field, `table));
});
return row;
}
global boolean AlwaysHideDisk(map<string, map> target_map, map disk)
{
boolean real_disk = Storage::IsPartitionable(disk);
symbol type = disk["type"]:`CT_UNKNOWN;
if (type == `CT_DISK && !real_disk)
return true;
if (!contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH, `CT_MDPART, `CT_LVM ], type))
return true;
return false;
}
global boolean AlwaysHidePartition(map<string, map> target_map, map disk, map partition)
{
if (partition["fsid"]:0 == Partitions::fsid_mac_hidden)
return true;
return false;
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateAll(map disk, map partition)
{
return `showandfollow;
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateDiskType(map disk, map partition, list<symbol> disk_types)
{
if (partition == nil)
{
if (contains(disk_types, disk["type"]:`CT_UNKNOWN))
return `showandfollow;
else
return `ignore;
}
else
{
return `show;
}
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateDiskDevice(map disk, map partition, list<string> disk_devices)
{
if (partition == nil)
{
if (contains(disk_devices, disk["device"]:""))
return `follow;
else
return `ignore;
}
else
{
return `show;
}
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateDevice(map disk, map partition, list<string> devices)
{
if (partition == nil)
{
if (contains(devices, disk["device"]:""))
return `showandfollow;
else
return `follow;
}
else
{
if (contains(devices, partition["device"]:""))
return `show;
else
return `ignore;
}
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateUsedByDevice(map disk, map partition, list<string> devices)
{
if (partition == nil)
{
if (find(map used_by, disk["used_by"]:[], { return contains(devices, used_by["device"]:""); }) != nil)
return `showandfollow;
else
return `follow;
}
else
{
if (find(map used_by, partition["used_by"]:[], { return contains(devices, used_by["device"]:""); }) != nil)
return `show;
else
return `ignore;
}
}
/**
* Predicate function for Table and TableContents.
*/
global symbol PredicateMountpoint(map disk, map partition)
{
if (partition == nil)
{
if (!isempty(disk["mount"]:""))
return `showandfollow;
else
return `follow;
}
else
{
if (!isempty(partition["mount"]:""))
return `show;
else
return `ignore;
}
}
/**
* The predicate function determines whether the disk/partition is
* included. The predicate function takes two arguments, disk and
* partition. For disks predicate is called with the partitions set to
* nil.
*
* Possible return values for predicate:
* `show, `follow, `showandfollow, `ignore
*/
global list<term> TableContents(list<symbol> fields, map<string, map> target_map,
symbol(map, map) predicate)
{
list<term> contents = [];
void callback(map<string, map> target_map, map disk)
{
symbol disk_predicate = predicate(disk, nil);
if (!AlwaysHideDisk(target_map, disk) &&
contains([`show, `showandfollow], disk_predicate))
{
term row = StorageFields::TableRow(fields, disk, nil);
contents = add(contents, row);
}
if (contains([`follow, `showandfollow], disk_predicate))
{
list<map> partitions = disk["partitions"]:[];
foreach(map partition, partitions, {
symbol part_predicate = predicate(disk, partition);
if (!AlwaysHidePartition(target_map, disk, partition) &&
contains([`show, `showandfollow], part_predicate))
{
term row = StorageFields::TableRow(fields, disk, partition);
contents = add(contents, row);
}
});
}
}
IterateTargetMap(target_map, callback);
return contents;
}
global term Table(list<symbol> fields, map<string, map> target_map,
symbol(map, map) predicate)
{
term header = TableHeader(fields);
list<term> content = TableContents(fields, target_map, predicate);
return `Table(`opt(`keepSorting), header, content);
}
global string TableHelptext(list<symbol> fields)
{
fields = filter(symbol field, fields, { return substring(tostring(field), 0, 8) != "`heading"; });
string initial = _("<p>The table contains:</p>");
string helptext = list::reduce(string tmp, symbol field, initial, fields, {
return tmp + Helptext(field, `table);
});
return helptext;
}
/**
* The device must be the device entry in the target-map, e.g. "/dev/sda1",
* not something like "LABEL=test".
*/
global string OverviewContents(list<symbol> fields, map<string, map> target_map, string device)
{
map disk = target_map[device]:nil;
map part = nil;
if (disk == nil)
{
foreach(string s, map d, target_map, {
part = find(map p, d["partitions"]:[], { return p["device"]:"" == device; });
if (part != nil) {
disk = d;
break;
}
});
}
list< list<symbol> > splitfields(list<symbol> fields)
{
list< list<symbol> > ret = [];
list<symbol> tmp = [];
foreach(symbol field, fields, {
if (substring(tostring(field), 0, 8) == "`heading") {
if (size(tmp) > 1)
ret = add(ret, tmp);
tmp = [ field ];
} else {
tmp = add(tmp, field);
}
});
if (size(tmp) > 1)
ret = add(ret, tmp);
return ret;
}
string Heading(symbol field)
{
switch (field) {
case `heading_device:
// heading
return _("Device:");
case `heading_filesystem:
// heading
return _("File System:");
case `heading_hd:
// heading
return _("Hard Disk:");
case `heading_fc:
// heading
return _("Fibre Channel:");
case `heading_lvm:
// heading
return _("LVM:");
case `heading_md:
// heading
return _("RAID:");
default:
y2error("unknown field %1", field);
return "error";
}
}
list<string> List(list<symbol> fields)
{
return maplist(symbol field, fields, {
// cast to string - overviews expect textual summary
return ( string ) MakeSubInfo(disk, part, field, `overview);
});
};
string content = mergestring(maplist(list<symbol> subfields, splitfields(fields), {
return HTML::Heading(Heading(subfields[0]:`none)) + HTML::List(List(sublist(subfields, 1)));
}), "");
return content;
}
global term Overview(list<symbol> fields, map<string, map> target_map, string device)
{
string contents = OverviewContents(fields, target_map, device);
return `RichText(`id(`text), `opt(`hstretch, `vstretch), contents);
}
global string OverviewHelptext(list<symbol> fields)
{
fields = filter(symbol field, fields, { return substring(tostring(field), 0, 8) != "`heading"; });
string initial = _("<p>The overview contains:</p>");
string helptext = list::reduce(string tmp, symbol field, initial, fields, {
return tmp + Helptext(field, `overview);
});
return helptext;
}
}
ACC SHELL 2018