CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyparted

Python bindings for GNU parted library providing disk partition management capabilities

Pending
Overview
Eval results
Files

constraint-solving.mddocs/

Constraint Solving

Constraint solving in pyparted provides a powerful system for ensuring partition operations respect device limitations, alignment requirements, size restrictions, and other complex requirements. Constraints are essential for safe and optimal partition management.

Capabilities

Constraint Class

The Constraint class describes restrictions and requirements for partition operations.

class Constraint:
    """
    Constraint describes restrictions on pyparted operations including
    location, alignment, and size requirements for partitions.
    """
    
    # Properties
    minSize: int        # Minimum allowed size in sectors
    maxSize: int        # Maximum allowed size in sectors
    startAlign: Alignment    # Start alignment requirements
    endAlign: Alignment      # End alignment requirements  
    startRange: Geometry     # Allowed range for start position
    endRange: Geometry       # Allowed range for end position

Constraint Creation

Multiple ways to create constraint objects for different scenarios.

class Constraint:
    def __init__(minGeom: Geometry = None, maxGeom: Geometry = None,
                 exactGeom: Geometry = None, device: Device = None,
                 startAlign: Alignment = None, endAlign: Alignment = None,
                 startRange: Geometry = None, endRange: Geometry = None,
                 minSize: int = None, maxSize: int = None) -> Constraint:
        """
        Create constraint object using various parameters.
        
        Args:
            minGeom (Geometry): Minimum geometry constraint
            maxGeom (Geometry): Maximum geometry constraint  
            exactGeom (Geometry): Exact geometry requirement
            device (Device): Device-wide constraint
            startAlign (Alignment): Start alignment requirement
            endAlign (Alignment): End alignment requirement
            startRange (Geometry): Allowed start position range
            endRange (Geometry): Allowed end position range
            minSize (int): Minimum size in sectors
            maxSize (int): Maximum size in sectors
            
        Raises:
            ConstraintException: If parameters are invalid or incompatible
        """

Constraint Operations

Methods for combining and manipulating constraints.

class Constraint:
    def intersect(constraint: Constraint) -> Constraint:
        """
        Create constraint representing intersection of two constraints.
        New constraint satisfies both original constraints.
        
        Args:
            constraint (Constraint): Constraint to intersect with
            
        Returns:
            Constraint: Intersection constraint
            
        Raises:
            CreateException: If intersection cannot be created
            ArithmeticError: If calculation fails
        """
    
    def duplicate() -> Constraint:
        """
        Create a copy of this constraint.
        
        Returns:
            Constraint: Duplicated constraint object
            
        Raises:
            CreateException: If duplication fails
        """

Constraint Solving

Methods for finding geometries that satisfy constraint requirements.

class Constraint:
    def solveMax(geometry: Geometry) -> Geometry:
        """
        Find largest geometry satisfying constraint near given geometry.
        
        Args:
            geometry (Geometry): Reference geometry for solving
            
        Returns:
            Geometry: Maximum geometry satisfying constraint
            
        Raises:
            ArithmeticError: If no solution exists
        """
    
    def solveNearest(geometry: Geometry) -> Geometry:
        """
        Find geometry satisfying constraint nearest to given geometry.
        
        Args:
            geometry (Geometry): Reference geometry for solving
            
        Returns:
            Geometry: Nearest geometry satisfying constraint
            
        Raises:
            ArithmeticError: If no solution exists
        """
    
    def isSolution(geometry: Geometry) -> bool:
        """
        Check if geometry satisfies this constraint.
        
        Args:
            geometry (Geometry): Geometry to test
            
        Returns:
            bool: True if geometry satisfies constraint
        """

Device Constraint Methods

Device objects provide convenient methods for creating common constraint types.

class Device:
    def getConstraint() -> Constraint:
        """
        Get constraint that accepts any region on device.
        
        Returns:
            Constraint: Device-wide constraint
        """
    
    def getMinimalAlignedConstraint() -> Constraint:
        """
        Get constraint with minimal alignment requirements.
        
        Returns:
            Constraint: Minimal alignment constraint
        """
    
    def getOptimalAlignedConstraint() -> Constraint:
        """
        Get constraint with optimal alignment for performance.
        
        Returns:
            Constraint: Optimal alignment constraint
        """

Usage Examples

Basic Constraint Creation

import parted

device = parted.getDevice('/dev/sda')

# Create device-wide constraint (accepts any region)
device_constraint = device.getConstraint()

# Create optimal alignment constraint
optimal_constraint = device.getOptimalAlignedConstraint()

# Create minimal alignment constraint  
minimal_constraint = device.getMinimalAlignedConstraint()

print("Constraints created for device operations")

Custom Constraint Creation

import parted

device = parted.getDevice('/dev/sdb')

# Get alignment requirements
start_alignment = device.getOptimumAlignment()
end_alignment = device.getOptimumAlignment()

# Define allowed ranges
device_geometry = parted.Geometry(device, start=0, length=device.length)
start_range = parted.Geometry(device, start=2048, length=device.length - 2048)
end_range = device_geometry

# Define size constraints (1GB to 100GB)
min_size = (1 * 1024**3) // device.sectorSize
max_size = (100 * 1024**3) // device.sectorSize

# Create custom constraint
custom_constraint = parted.Constraint(
    startAlign=start_alignment,
    endAlign=end_alignment,
    startRange=start_range,
    endRange=end_range,
    minSize=min_size,
    maxSize=max_size
)

print(f"Custom constraint: min={min_size}, max={max_size} sectors")

Constraint Intersection

import parted

device = parted.getDevice('/dev/sda')

# Create different constraints
size_constraint = parted.Constraint(
    startAlign=device.getMinimumAlignment(),
    endAlign=device.getMinimumAlignment(),
    startRange=parted.Geometry(device, start=0, length=device.length),
    endRange=parted.Geometry(device, start=0, length=device.length),
    minSize=1000000,  # ~500MB
    maxSize=2000000   # ~1GB
)

alignment_constraint = device.getOptimalAlignedConstraint()

# Intersect constraints to get one that satisfies both
combined_constraint = size_constraint.intersect(alignment_constraint)

print("Combined constraint created with size and alignment requirements")

Constraint Solving

import parted

device = parted.getDevice('/dev/sdb')
disk = parted.newDisk(device)

# Create constraint for new partition
constraint = device.getOptimalAlignedConstraint()

# Define desired geometry (10GB starting at sector 2048)
desired_start = 2048
desired_size = (10 * 1024**3) // device.sectorSize
desired_geometry = parted.Geometry(device, start=desired_start, length=desired_size)

# Check if desired geometry satisfies constraint
if constraint.isSolution(desired_geometry):
    print("Desired geometry satisfies constraint")
    final_geometry = desired_geometry
else:
    print("Adjusting geometry to satisfy constraint")
    
    # Find nearest geometry that satisfies constraint
    final_geometry = constraint.solveNearest(desired_geometry)
    
    # Or find maximum geometry that satisfies constraint
    # final_geometry = constraint.solveMax(desired_geometry)

print(f"Final geometry: start={final_geometry.start}, length={final_geometry.length}")

# Create partition with solved geometry
partition = parted.Partition(
    disk=disk,
    type=parted.PARTITION_NORMAL,
    geometry=final_geometry
)

disk.addPartition(partition, constraint)
disk.commit()

Constraint-Based Partition Resizing

import parted

device = parted.getDevice('/dev/sdc')
disk = parted.newDisk(device)
partition = disk.getPartitionByNumber(1)

if partition and not partition.isBusy():
    # Create constraint for resizing
    constraint = device.getOptimalAlignedConstraint()
    
    # Try to maximize partition
    try:
        max_geometry = constraint.solveMax(partition.geometry)
        print(f"Maximum possible size: {max_geometry.length} sectors")
        
        # Apply maximum geometry
        disk.setPartitionGeometry(
            partition,
            constraint,
            max_geometry.start,
            max_geometry.end
        )
        
        disk.commit()
        print("Partition maximized successfully")
        
    except ArithmeticError:
        print("Cannot find larger geometry satisfying constraints")

Complex Constraint Scenarios

import parted

device = parted.getDevice('/dev/sda')

# Create constraint for system partition (small, at beginning)
system_geometry = parted.Geometry(device, start=2048, length=1048576)  # ~512MB
system_constraint = parted.Constraint(exactGeom=system_geometry)

# Create constraint for data partition (rest of disk, optimally aligned)
data_start = 2048 + 1048576
data_length = device.length - data_start - 1024  # Leave space at end
data_range = parted.Geometry(device, start=data_start, length=data_length)

data_constraint = parted.Constraint(
    startAlign=device.getOptimumAlignment(),
    endAlign=device.getOptimumAlignment(),
    startRange=data_range,
    endRange=data_range,
    minSize=data_length // 2,  # At least half the available space
    maxSize=data_length
)

print("Created constraints for system and data partitions")

# Test if constraints can be satisfied
test_system_geom = parted.Geometry(device, start=2048, length=1048576)
test_data_geom = parted.Geometry(device, start=data_start, length=data_length)

system_ok = system_constraint.isSolution(test_system_geom)
data_ok = data_constraint.isSolution(test_data_geom)

print(f"System constraint satisfied: {system_ok}")
print(f"Data constraint satisfied: {data_ok}")

Constraint Debugging

import parted

device = parted.getDevice('/dev/sda')
constraint = device.getOptimalAlignedConstraint()

# Create test geometry
test_geometry = parted.Geometry(device, start=1000, length=2000000)

if not constraint.isSolution(test_geometry):
    print("Geometry doesn't satisfy constraint")
    
    # Try to find what would work
    try:
        nearest = constraint.solveNearest(test_geometry)
        max_geom = constraint.solveMax(test_geometry)
        
        print(f"Original: start={test_geometry.start}, length={test_geometry.length}")
        print(f"Nearest:  start={nearest.start}, length={nearest.length}")  
        print(f"Maximum:  start={max_geom.start}, length={max_geom.length}")
        
    except ArithmeticError as e:
        print(f"No solution found: {e}")
else:
    print("Geometry satisfies constraint")

Constraint Types

Geometry-Based Constraints

  • Exact Geometry: Partition must use specific geometry
  • Min/Max Geometry: Partition must fit within bounds
  • Device Constraint: Any region on device is acceptable

Alignment Constraints

  • Start Alignment: Start sector must be aligned
  • End Alignment: End sector must be aligned
  • Combined Alignment: Both start and end aligned

Size Constraints

  • Minimum Size: Partition must be at least specified size
  • Maximum Size: Partition cannot exceed specified size
  • Size Range: Partition size must be within range

Position Constraints

  • Start Range: Start sector must be within range
  • End Range: End sector must be within range
  • Region Constraint: Entire partition within region

Best Practices

  1. Always Use Constraints: Never create partitions without constraints
  2. Combine Constraints: Use intersection for multiple requirements
  3. Check Solutions: Verify geometries satisfy constraints before use
  4. Handle Failures: Be prepared for unsolvable constraint scenarios
  5. Use Device Constraints: Leverage device-provided constraints for safety

Install with Tessl CLI

npx tessl i tessl/pypi-pyparted

docs

constants-reference.md

constraint-solving.md

device-management.md

disk-operations.md

exception-handling.md

filesystem-operations.md

geometry-alignment.md

index.md

partition-management.md

utility-functions.md

tile.json