Skip to content

Conversation

@lollipopkit
Copy link
Owner

@lollipopkit lollipopkit commented Sep 1, 2025

Fixes #853

Summary by Sourcery

Improve disk parsing resilience by falling back to 'df -k' and handling missing or invalid fs fields gracefully

New Features:

  • Add fallback to use 'df -k' when 'lsblk' output is unavailable or incompatible

Enhancements:

  • Guard against missing or 'null' filesystem size, used, available, and usage percent fields by defaulting to zero

Tests:

  • Add unit test for parsing 'df -k' output in fallback mode

@sourcery-ai
Copy link

sourcery-ai bot commented Sep 1, 2025

Reviewer's Guide

Introduce fallback to df -k for disk metrics on incompatible systems by extending the shell command, adding defensive parsing for FS fields in the Disk model, and covering the new path with unit tests.

Class diagram for updated Disk model parsing

classDiagram
class Disk {
  +BigInt size
  +BigInt used
  +BigInt avail
  +int usedPercent
  +fromJson(Map device)
}
Disk : fromJson() parses size, used, avail, usedPercent defensively
Disk : fromJson() supports fallback fields from `df -k` output
Loading

File-Level Changes

Change Details Files
Add defensive parsing for filesystem size, used, available, and usage fields
  • Wrap parsing of fssize, fsused, fsavail, and fsuse% strings in conditional checks against '0', empty, or 'null'
  • Default BigInt or int values to zero when fields are missing or invalid
  • Duplicate the same parsing logic in both primary and fallback branches
lib/data/model/server/disk.dart
Extend disk command to fallback to df -k
  • Append `
Add unit tests for parsing df -k output
  • Introduce a new test case that runs Disk.parse against sample df -k output
  • Verify detection and correct parsing of multiple filesystems (udev, root, EFI) with size, used, avail, and usage percentage
test/disk_test.dart

Assessment against linked issues

Issue Objective Addressed Explanation
#853 Ensure partition information is displayed on all servers, including those where the default command is incompatible.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@lollipopkit
Copy link
Owner Author

@claude review the fallback logic

@claude
Copy link

claude bot commented Sep 1, 2025

Claude finished @lollipopkit's task —— View job


Code Review of Fallback Logic

Todo List:

  • Read repository setup instructions (CLAUDE.md)
  • Review the command modification in cmd_types.dart
  • Review the defensive parsing logic in disk.dart
  • Review the test coverage in disk_test.dart
  • Analyze fallback logic for potential issues
  • Provide comprehensive review feedback

Review Findings

The fallback logic implementation is well-designed and robust. Here's my detailed analysis:

Strengths

1. Command Fallback Strategy (cmd_types.dart:57-61)

  • The || df -k fallback is simple and effective
  • df -k is universally available on Unix-like systems
  • Properly placed after the full lsblk command to only execute if lsblk fails

2. Defensive Parsing (disk.dart:106-130)

  • Excellent null safety with multiple validation layers:
    • Checks for '0', empty string, and 'null' string values
    • Uses BigInt.tryParse() with fallback to BigInt.zero
    • Consistent pattern applied to all numeric fields (fssize, fsused, fsavail, fsuse%)

3. Code Reuse and Maintainability

  • The defensive parsing logic is correctly duplicated in both _processSingleDevice() and _processDiskDevice() methods
  • Both JSON and fallback parsing paths are well-handled

4. Comprehensive Test Coverage (disk_test.dart:85-109)

  • Tests verify the fallback parsing with actual df -k output
  • Validates correct handling of different filesystem types
  • Tests edge cases like zero-size filesystems

⚠️ Minor Suggestions for Improvement

1. Code Duplication (disk.dart:106-130 & 172-196)
The defensive parsing logic is duplicated between _processSingleDevice() and _processDiskDevice(). Consider extracting this into a helper method:

static ({BigInt size, BigInt used, BigInt avail, int usedPercent}) _parseFilesystemFields(Map<String, dynamic> device) {
  // Extract common parsing logic here
}

2. Error Handling Enhancement
The current try-catch in parse() (line 61) logs warnings but continues. This is appropriate, but you might consider:

  • More specific error messages indicating whether JSON parsing or fallback parsing failed
  • Potentially different handling strategies for different error types

3. Documentation
Consider adding inline comments explaining when the fallback scenario occurs:

disk(
  'lsblk --bytes --json --output '
  'FSTYPE,PATH,NAME,KNAME,MOUNTPOINT,FSSIZE,FSUSED,FSAVAIL,FSUSE%,UUID '
  '|| df -k' // Fallback when lsblk is unavailable or incompatible
),

Security and Performance Assessment

  • No security concerns: The fallback uses standard system commands without user input injection
  • Performance impact: Minimal - fallback only executes when primary command fails
  • Error resilience: Excellent - handles various failure modes gracefully

Test Coverage Analysis

The test suite appropriately covers:

  • JSON parsing from lsblk output
  • Fallback parsing from df -k output
  • Edge cases (null values, zero sizes)
  • Parent-child device relationships

Final Assessment

This is a solid implementation that effectively addresses issue #853. The fallback logic is:

  • ✅ Robust and handles edge cases well
  • ✅ Maintains backward compatibility
  • ✅ Has appropriate test coverage
  • ✅ Follows existing code patterns
  • ✅ Implements proper error handling

The code is ready for merge with only minor suggestions for future enhancement.


@lollipopkit
Copy link
Owner Author

@claude review again, focus on reliability and compatibility

@claude
Copy link

claude bot commented Sep 1, 2025

Claude finished @lollipopkit's task —— View job


Reliability and Compatibility Review

Todo List:

  • Read repository setup instructions (CLAUDE.md)
  • Review command fallback strategy for compatibility
  • Analyze defensive parsing for reliability
  • Test edge cases and error scenarios
  • Evaluate cross-platform compatibility
  • Provide comprehensive reliability and compatibility assessment

Comprehensive Reliability and Compatibility Assessment

After thoroughly analyzing the fallback logic implementation, here is my focused review on reliability and compatibility:

Reliability Strengths

1. Robust Command Fallback Architecture (cmd_types.dart:57-61)

  • Primary Command: lsblk --bytes --json with comprehensive output fields
  • Fallback Trigger: Uses shell || operator - fallback only executes if primary command exits with non-zero status
  • Success Detection: Implements LSBLK_SUCCESS marker to distinguish between partial JSON output and complete success
  • Universal Fallback: df -k is POSIX-compliant and available on virtually all Unix-like systems

2. Defensive Parsing Logic (disk.dart:119-142)
The _parseFilesystemFields() method implements excellent defensive programming:

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);
}
  • Handles null, empty strings, string "null", and "0" values
  • Uses tryParse() with fallback to prevent exceptions
  • Consistent pattern across all numeric fields

3. Multi-Layer Error Handling (disk.dart:53-92)

  • JSON parsing failures trigger automatic fallback to df -k parsing
  • Graceful degradation: if primary parsing fails, secondary method is attempted
  • Both parsing methods use try-catch with continue-on-error behavior
  • Comprehensive logging for debugging without breaking functionality

4. Extensive Test Coverage (disk_test.dart:85-561)
Tests cover critical reliability scenarios:

  • Null field handling (lines 121-131, 133-143, 145-155)
  • Invalid data formats (lines 157-175)
  • Malformed JSON recovery (lines 177-180)
  • Parsing edge cases and boundary conditions

Compatibility Strengths

1. Cross-Platform Command Support

  • Linux: Primary lsblk command with comprehensive JSON output
  • BSD/macOS: Already uses df -k as primary command (line 144) - no fallback needed
  • Universal: df -k works identically across Linux, BSD, macOS, Solaris, AIX

2. Command Compatibility Matrix

System      | Primary Command | Fallback Command | Compatibility
Linux       | lsblk --json   | df -k            | ✅ Full
BSD/macOS   | df -k          | (none needed)    | ✅ Native  
Solaris     | (would use)    | df -k            | ✅ Compatible
AIX         | (would use)    | df -k            | ✅ Compatible

3. Output Format Compatibility

  • lsblk JSON output: Rich metadata (UUID, device names, parent-child relationships)
  • df -k output: Universal POSIX format, consistent field structure across platforms
  • Both formats handled by the same parsing infrastructure

4. Filesystem Type Compatibility
The _shouldCalc() function (lines 415-436) handles diverse filesystem scenarios:

  • Standard filesystems: ext2/3/4, xfs, btrfs, zfs, ntfs
  • Network filesystems: NFS, CIFS (//192.168.1.2/ format)
  • Mounted volumes: /mnt paths
  • Excludes virtual filesystems: tmpfs, overlay, shm (appropriate filtering)

⚠️ Potential Compatibility Concerns

1. Command Availability Edge Cases

  • Some minimal container images might lack lsblk (fallback handles this)
  • Some embedded systems might have limited df implementations
  • Mitigation: The fallback is already battle-tested across platforms

2. Parsing Assumption Dependencies

  • df -k assumes POSIX-compliant output format
  • Some proprietary Unix variants might have slight format variations
  • Risk Level: Low - df -k format is highly standardized

3. Locale and Character Encoding

  • Commands might produce localized output on non-English systems
  • Current Status: Code doesn't explicitly handle locale variations
  • Impact: Header parsing might fail on non-English systems

🔧 Reliability Enhancement Opportunities

1. Locale Independence

# Consider: LC_ALL=C lsblk ... || LC_ALL=C df -k

This would ensure consistent English output regardless of system locale.

2. Command Existence Verification
While the fallback works well, explicit command checking could provide better error messages:

(lsblk --version >/dev/null 2>&1 && lsblk ...) || df -k

3. Timeout Protection
Both commands are typically fast, but adding timeouts could prevent hanging on network filesystems:

timeout 10 lsblk ... || timeout 10 df -k

📊 Final Reliability and Compatibility Score

Aspect Score Rationale
Error Handling 9/10 Comprehensive exception handling, graceful fallbacks
Cross-Platform 9/10 Excellent POSIX compliance, universal df -k support
Edge Case Handling 9/10 Defensive parsing, null safety, malformed data handling
Command Reliability 8/10 Robust fallback strategy, minimal assumptions
Parsing Resilience 9/10 Multiple parsing methods, comprehensive validation
Test Coverage 9/10 Extensive test suite covering edge cases

Overall Assessment: 8.7/10 - Excellent

🎯 Conclusion

This fallback logic implementation demonstrates exceptional reliability and compatibility. The architecture properly handles:

  • System Compatibility: Works across all major Unix-like platforms
  • Command Failures: Graceful degradation from JSON to tabular parsing
  • Data Integrity: Defensive parsing prevents crashes on malformed data
  • Error Recovery: Multiple fallback layers ensure functionality even in adverse conditions
  • Future-Proof: POSIX-compliant fallback ensures long-term compatibility

The implementation successfully addresses issue #853 by providing a robust solution for displaying partition information across incompatible systems. The fallback logic is production-ready and demonstrates excellent software engineering practices.


@lollipopkit lollipopkit merged commit 8e4c2a7 into main Sep 1, 2025
1 check passed
@lollipopkit lollipopkit deleted the lollipopkit/issue853 branch September 1, 2025 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hello, in version 1206, partition information is not displayed on some servers. I hope this can be corrected.

2 participants