mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 15:24:35 +01:00
fix: fallback to df on incompatible system (#880)
This commit is contained in:
@@ -55,8 +55,8 @@ enum StatusCmdType implements ShellCmdType {
|
|||||||
uptime('uptime'),
|
uptime('uptime'),
|
||||||
conn('cat /proc/net/snmp'),
|
conn('cat /proc/net/snmp'),
|
||||||
disk(
|
disk(
|
||||||
'lsblk --bytes --json --output '
|
'(lsblk --bytes --json --output '
|
||||||
'FSTYPE,PATH,NAME,KNAME,MOUNTPOINT,FSSIZE,FSUSED,FSAVAIL,FSUSE%,UUID',
|
'FSTYPE,PATH,NAME,KNAME,MOUNTPOINT,FSSIZE,FSUSED,FSAVAIL,FSUSE%,UUID 2>/dev/null && echo "LSBLK_SUCCESS") || df -k'
|
||||||
),
|
),
|
||||||
mem("cat /proc/meminfo | grep -E 'Mem|Swap'"),
|
mem("cat /proc/meminfo | grep -E 'Mem|Swap'"),
|
||||||
tempType('cat /sys/class/thermal/thermal_zone*/type'),
|
tempType('cat /sys/class/thermal/thermal_zone*/type'),
|
||||||
|
|||||||
@@ -44,22 +44,49 @@ class Disk with EquatableMixin {
|
|||||||
static List<Disk> parse(String raw) {
|
static List<Disk> parse(String raw) {
|
||||||
final list = <Disk>[];
|
final list = <Disk>[];
|
||||||
raw = raw.trim();
|
raw = raw.trim();
|
||||||
try {
|
|
||||||
if (raw.startsWith('{')) {
|
if (raw.isEmpty) {
|
||||||
// Parse JSON output from lsblk command
|
dprint('Empty disk info data received');
|
||||||
final Map<String, dynamic> jsonData = json.decode(raw);
|
return list;
|
||||||
final List<dynamic> blockdevices = jsonData['blockdevices'] ?? [];
|
}
|
||||||
|
|
||||||
for (final device in blockdevices) {
|
try {
|
||||||
// Process each device
|
// Check if we have lsblk JSON output with success marker
|
||||||
_processTopLevelDevice(device, list);
|
if (raw.startsWith('{')) {
|
||||||
|
// Extract JSON part (excluding the success marker if present)
|
||||||
|
final jsonEnd = raw.indexOf('\nLSBLK_SUCCESS');
|
||||||
|
final jsonPart = jsonEnd > 0 ? raw.substring(0, jsonEnd) : raw;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Map<String, dynamic> jsonData = json.decode(jsonPart);
|
||||||
|
final List<dynamic> blockdevices = jsonData['blockdevices'] ?? [];
|
||||||
|
|
||||||
|
for (final device in blockdevices) {
|
||||||
|
// Process each device
|
||||||
|
_processTopLevelDevice(device, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we successfully parsed JSON and have valid disks, return them
|
||||||
|
if (list.isNotEmpty) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
} on FormatException catch (e) {
|
||||||
|
Loggers.app.warning('JSON parsing failed, falling back to df -k output: $e');
|
||||||
|
} catch (e) {
|
||||||
|
Loggers.app.warning('Error processing JSON disk data, falling back to df -k output: $e', e);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// Fallback to the old parsing method in case of non-JSON output
|
|
||||||
|
// Check if we have df -k output (fallback case)
|
||||||
|
if (raw.contains('Filesystem') && raw.contains('Mounted on')) {
|
||||||
return _parseWithOldMethod(raw);
|
return _parseWithOldMethod(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we reach here, both parsing methods failed
|
||||||
|
Loggers.app.warning('Unable to parse disk info with any method');
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Loggers.app.warning('Failed to parse disk info: $e', e);
|
Loggers.app.warning('Failed to parse disk info with both methods: $e', e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -88,6 +115,32 @@ class Disk with EquatableMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse filesystem fields from device data
|
||||||
|
static ({BigInt size, BigInt used, BigInt avail, int usedPercent}) _parseFilesystemFields(Map<String, dynamic> device) {
|
||||||
|
// Helper function to parse size strings safely
|
||||||
|
BigInt parseSize(String? sizeStr) {
|
||||||
|
if (sizeStr == null || sizeStr.isEmpty || sizeStr == 'null' || sizeStr == '0') {
|
||||||
|
return BigInt.zero;
|
||||||
|
}
|
||||||
|
return (BigInt.tryParse(sizeStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to parse percentage strings
|
||||||
|
int parsePercent(String? percentStr) {
|
||||||
|
if (percentStr == null || percentStr.isEmpty || percentStr == 'null') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return int.tryParse(percentStr.replaceAll('%', '')) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
size: parseSize(device['fssize']?.toString()),
|
||||||
|
used: parseSize(device['fsused']?.toString()),
|
||||||
|
avail: parseSize(device['fsavail']?.toString()),
|
||||||
|
usedPercent: parsePercent(device['fsuse%']?.toString()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Process a single device without recursively processing its children
|
/// Process a single device without recursively processing its children
|
||||||
static Disk? _processSingleDevice(Map<String, dynamic> device) {
|
static Disk? _processSingleDevice(Map<String, dynamic> device) {
|
||||||
final fstype = device['fstype']?.toString();
|
final fstype = device['fstype']?.toString();
|
||||||
@@ -102,20 +155,7 @@ class Disk with EquatableMixin {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final sizeStr = device['fssize']?.toString() ?? '0';
|
final fsFields = _parseFilesystemFields(device);
|
||||||
final size = (BigInt.tryParse(sizeStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
final usedStr = device['fsused']?.toString() ?? '0';
|
|
||||||
final used = (BigInt.tryParse(usedStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
final availStr = device['fsavail']?.toString() ?? '0';
|
|
||||||
final avail = (BigInt.tryParse(availStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
// Parse fsuse% which is usually in the format "45%"
|
|
||||||
String usePercentStr = device['fsuse%']?.toString() ?? '0';
|
|
||||||
usePercentStr = usePercentStr.replaceAll('%', '');
|
|
||||||
final usedPercent = int.tryParse(usePercentStr) ?? 0;
|
|
||||||
|
|
||||||
final name = device['name']?.toString();
|
final name = device['name']?.toString();
|
||||||
final kname = device['kname']?.toString();
|
final kname = device['kname']?.toString();
|
||||||
final uuid = device['uuid']?.toString();
|
final uuid = device['uuid']?.toString();
|
||||||
@@ -124,10 +164,10 @@ class Disk with EquatableMixin {
|
|||||||
path: path,
|
path: path,
|
||||||
fsTyp: fstype,
|
fsTyp: fstype,
|
||||||
mount: mountpoint,
|
mount: mountpoint,
|
||||||
usedPercent: usedPercent,
|
usedPercent: fsFields.usedPercent,
|
||||||
used: used,
|
used: fsFields.used,
|
||||||
size: size,
|
size: fsFields.size,
|
||||||
avail: avail,
|
avail: fsFields.avail,
|
||||||
name: name,
|
name: name,
|
||||||
kname: kname,
|
kname: kname,
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
@@ -155,20 +195,7 @@ class Disk with EquatableMixin {
|
|||||||
|
|
||||||
// Handle common filesystem cases or parent devices with children
|
// Handle common filesystem cases or parent devices with children
|
||||||
if ((fstype != null && _shouldCalc(fstype, mount)) || (childDisks.isNotEmpty && path.isNotEmpty)) {
|
if ((fstype != null && _shouldCalc(fstype, mount)) || (childDisks.isNotEmpty && path.isNotEmpty)) {
|
||||||
final sizeStr = device['fssize']?.toString() ?? '0';
|
final fsFields = _parseFilesystemFields(device);
|
||||||
final size = (BigInt.tryParse(sizeStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
final usedStr = device['fsused']?.toString() ?? '0';
|
|
||||||
final used = (BigInt.tryParse(usedStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
final availStr = device['fsavail']?.toString() ?? '0';
|
|
||||||
final avail = (BigInt.tryParse(availStr) ?? BigInt.zero) ~/ BigInt.from(1024);
|
|
||||||
|
|
||||||
// Parse fsuse% which is usually in the format "45%"
|
|
||||||
String usePercentStr = device['fsuse%']?.toString() ?? '0';
|
|
||||||
usePercentStr = usePercentStr.replaceAll('%', '');
|
|
||||||
final usedPercent = int.tryParse(usePercentStr) ?? 0;
|
|
||||||
|
|
||||||
final name = device['name']?.toString();
|
final name = device['name']?.toString();
|
||||||
final kname = device['kname']?.toString();
|
final kname = device['kname']?.toString();
|
||||||
final uuid = device['uuid']?.toString();
|
final uuid = device['uuid']?.toString();
|
||||||
@@ -177,10 +204,10 @@ class Disk with EquatableMixin {
|
|||||||
path: path,
|
path: path,
|
||||||
fsTyp: fstype,
|
fsTyp: fstype,
|
||||||
mount: mount,
|
mount: mount,
|
||||||
usedPercent: usedPercent,
|
usedPercent: fsFields.usedPercent,
|
||||||
used: used,
|
used: fsFields.used,
|
||||||
size: size,
|
size: fsFields.size,
|
||||||
avail: avail,
|
avail: fsFields.avail,
|
||||||
name: name,
|
name: name,
|
||||||
kname: kname,
|
kname: kname,
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
|
|||||||
@@ -81,6 +81,138 @@ void main() {
|
|||||||
expect(usage.usedPercent, 50);
|
expect(usage.usedPercent, 50);
|
||||||
// This would use the "unknown" fallback for kname
|
// This would use the "unknown" fallback for kname
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('parse df -k output (fallback mode)', () {
|
||||||
|
final disks = Disk.parse(_dfOutput);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
expect(disks.length, 3); // Should find 3 valid filesystems: udev, /dev/vda3, /dev/vda2
|
||||||
|
|
||||||
|
// Verify root filesystem
|
||||||
|
final rootFs = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(rootFs.path, '/dev/vda3');
|
||||||
|
expect(rootFs.usedPercent, 47);
|
||||||
|
expect(rootFs.size, BigInt.from(40910528 ~/ 1024)); // df -k output divided by 1024 = MB
|
||||||
|
expect(rootFs.used, BigInt.from(18067948 ~/ 1024));
|
||||||
|
expect(rootFs.avail, BigInt.from(20951380 ~/ 1024));
|
||||||
|
|
||||||
|
// Verify boot/efi filesystem
|
||||||
|
final efiFs = disks.firstWhere((disk) => disk.mount == '/boot/efi');
|
||||||
|
expect(efiFs.path, '/dev/vda2');
|
||||||
|
expect(efiFs.usedPercent, 7);
|
||||||
|
expect(efiFs.size, BigInt.from(192559 ~/ 1024));
|
||||||
|
|
||||||
|
// Verify udev filesystem is included (virtual filesystem)
|
||||||
|
final udevFs = disks.firstWhere((disk) => disk.path == 'udev');
|
||||||
|
expect(udevFs.mount, '/dev');
|
||||||
|
expect(udevFs.usedPercent, 0);
|
||||||
|
expect(udevFs.size, BigInt.from(864088 ~/ 1024));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle empty input gracefully', () {
|
||||||
|
final disks = Disk.parse('');
|
||||||
|
expect(disks, isEmpty);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle whitespace-only input', () {
|
||||||
|
final disks = Disk.parse(' \n\t \r\n ');
|
||||||
|
expect(disks, isEmpty);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON with null filesystem fields', () {
|
||||||
|
final disks = Disk.parse(_jsonWithNullFields);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle null filesystem fields gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.size, BigInt.zero);
|
||||||
|
expect(disk.used, BigInt.zero);
|
||||||
|
expect(disk.avail, BigInt.zero);
|
||||||
|
expect(disk.usedPercent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON with string "null" values', () {
|
||||||
|
final disks = Disk.parse(_jsonWithStringNulls);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle string "null" filesystem fields gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.size, BigInt.zero);
|
||||||
|
expect(disk.used, BigInt.zero);
|
||||||
|
expect(disk.avail, BigInt.zero);
|
||||||
|
expect(disk.usedPercent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON with empty string values', () {
|
||||||
|
final disks = Disk.parse(_jsonWithEmptyStrings);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle empty string filesystem fields gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.size, BigInt.zero);
|
||||||
|
expect(disk.used, BigInt.zero);
|
||||||
|
expect(disk.avail, BigInt.zero);
|
||||||
|
expect(disk.usedPercent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON with invalid percentage format', () {
|
||||||
|
final disks = Disk.parse(_jsonWithInvalidPercent);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle invalid percentage gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.usedPercent, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON with malformed numbers', () {
|
||||||
|
final disks = Disk.parse(_jsonWithMalformedNumbers);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle malformed numbers gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.size, BigInt.zero);
|
||||||
|
expect(disk.used, BigInt.zero);
|
||||||
|
expect(disk.avail, BigInt.zero);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle JSON parsing errors gracefully', () {
|
||||||
|
final disks = Disk.parse(_malformedJson);
|
||||||
|
expect(disks, isEmpty); // Should fallback to legacy method, which also fails
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle df output with missing fields', () {
|
||||||
|
final disks = Disk.parse(_dfWithMissingFields);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle missing fields gracefully
|
||||||
|
final disk = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(disk.usedPercent, 47);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle df output with inconsistent formatting', () {
|
||||||
|
final disks = Disk.parse(_dfWithInconsistentFormatting);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should handle inconsistent formatting
|
||||||
|
expect(disks.length, greaterThan(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle lsblk with success marker', () {
|
||||||
|
final disks = Disk.parse(_lsblkWithSuccessMarker);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should parse JSON and ignore success marker
|
||||||
|
final rootFs = disks.firstWhere((disk) => disk.mount == '/');
|
||||||
|
expect(rootFs.fsTyp, 'ext4');
|
||||||
|
expect(rootFs.usedPercent, 56);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handle malformed lsblk output fallback', () {
|
||||||
|
final disks = Disk.parse(_malformedLsblkWithDfFallback);
|
||||||
|
expect(disks, isNotEmpty);
|
||||||
|
|
||||||
|
// Should fallback to df -k parsing when lsblk output is malformed
|
||||||
|
expect(disks.length, 3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,3 +410,151 @@ overlay 1907116416 5470
|
|||||||
v2000pro/pve 1906694784 125440 1906569344 1% /mnt/v2000pro/pve
|
v2000pro/pve 1906694784 125440 1906569344 1% /mnt/v2000pro/pve
|
||||||
v2000pro/download 1906569472 128 1906569344 1% /mnt/v2000pro/download''',
|
v2000pro/download 1906569472 128 1906569344 1% /mnt/v2000pro/download''',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const _dfOutput = '''
|
||||||
|
Filesystem 1K-blocks Used Available Use% Mounted on
|
||||||
|
udev 864088 0 864088 0% /dev
|
||||||
|
tmpfs 176724 688 176036 1% /run
|
||||||
|
/dev/vda3 40910528 18067948 20951380 47% /
|
||||||
|
tmpfs 883612 0 883612 0% /dev/shm
|
||||||
|
tmpfs 5120 0 5120 0% /run/lock
|
||||||
|
/dev/vda2 192559 11807 180752 7% /boot/efi
|
||||||
|
tmpfs 176720 104 176616 1% /run/user/1000
|
||||||
|
''';
|
||||||
|
|
||||||
|
// Test data for edge cases
|
||||||
|
const _jsonWithNullFields = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": null,
|
||||||
|
"fsused": null,
|
||||||
|
"fsavail": null,
|
||||||
|
"fsuse%": null,
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _jsonWithStringNulls = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": "null",
|
||||||
|
"fsused": "null",
|
||||||
|
"fsavail": "null",
|
||||||
|
"fsuse%": "null",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _jsonWithEmptyStrings = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": "",
|
||||||
|
"fsused": "",
|
||||||
|
"fsavail": "",
|
||||||
|
"fsuse%": "",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _jsonWithInvalidPercent = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": "1000000",
|
||||||
|
"fsused": "500000",
|
||||||
|
"fsavail": "500000",
|
||||||
|
"fsuse%": "invalid_percent",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _jsonWithMalformedNumbers = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": "not_a_number",
|
||||||
|
"fsused": "invalid",
|
||||||
|
"fsavail": "broken",
|
||||||
|
"fsuse%": "50%",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _malformedJson = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": "1000000",
|
||||||
|
"fsused": "500000",
|
||||||
|
"fsavail": "500000",
|
||||||
|
"fsuse%": "50%",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// Missing closing brace and malformed structure
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _dfWithMissingFields = '''
|
||||||
|
Filesystem 1K-blocks Used Available Use% Mounted on
|
||||||
|
/dev/vda3 40910528 18067948 20951380 47% /
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _dfWithInconsistentFormatting = '''
|
||||||
|
Filesystem 1K-blocks Used Available Use% Mounted on
|
||||||
|
/dev/sda1 1000000 500000 500000 50% /
|
||||||
|
/dev/sda2 2000000 1000000 1000000 50% /home
|
||||||
|
udev 864088 0 864088 0% /dev
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _lsblkWithSuccessMarker = '''
|
||||||
|
{
|
||||||
|
"blockdevices": [
|
||||||
|
{
|
||||||
|
"fstype": "ext4",
|
||||||
|
"mountpoint": "/",
|
||||||
|
"fssize": 982141468672,
|
||||||
|
"fsused": 552718364672,
|
||||||
|
"fsavail": 379457622016,
|
||||||
|
"fsuse%": "56%",
|
||||||
|
"path": "/dev/sda1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
LSBLK_SUCCESS
|
||||||
|
''';
|
||||||
|
|
||||||
|
const _malformedLsblkWithDfFallback = '''
|
||||||
|
Filesystem 1K-blocks Used Available Use% Mounted on
|
||||||
|
udev 864088 0 864088 0% /dev
|
||||||
|
tmpfs 176724 688 176036 1% /run
|
||||||
|
/dev/vda3 40910528 18067948 20951380 47% /
|
||||||
|
tmpfs 883612 0 883612 0% /dev/shm
|
||||||
|
tmpfs 5120 0 5120 0% /run/lock
|
||||||
|
/dev/vda2 192559 11807 180752 7% /boot/efi
|
||||||
|
tmpfs 176720 104 176616 1% /run/user/1000
|
||||||
|
''';
|
||||||
|
|||||||
Reference in New Issue
Block a user