Python bindings for GNU parted library providing disk partition management capabilities
—
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.
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 positionMultiple 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
"""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
"""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 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
"""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")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")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")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()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")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}")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")Install with Tessl CLI
npx tessl i tessl/pypi-pyparted