0
# Constraint Solving
1
2
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.
3
4
## Capabilities
5
6
### Constraint Class
7
8
The Constraint class describes restrictions and requirements for partition operations.
9
10
```python { .api }
11
class Constraint:
12
"""
13
Constraint describes restrictions on pyparted operations including
14
location, alignment, and size requirements for partitions.
15
"""
16
17
# Properties
18
minSize: int # Minimum allowed size in sectors
19
maxSize: int # Maximum allowed size in sectors
20
startAlign: Alignment # Start alignment requirements
21
endAlign: Alignment # End alignment requirements
22
startRange: Geometry # Allowed range for start position
23
endRange: Geometry # Allowed range for end position
24
```
25
26
### Constraint Creation
27
28
Multiple ways to create constraint objects for different scenarios.
29
30
```python { .api }
31
class Constraint:
32
def __init__(minGeom: Geometry = None, maxGeom: Geometry = None,
33
exactGeom: Geometry = None, device: Device = None,
34
startAlign: Alignment = None, endAlign: Alignment = None,
35
startRange: Geometry = None, endRange: Geometry = None,
36
minSize: int = None, maxSize: int = None) -> Constraint:
37
"""
38
Create constraint object using various parameters.
39
40
Args:
41
minGeom (Geometry): Minimum geometry constraint
42
maxGeom (Geometry): Maximum geometry constraint
43
exactGeom (Geometry): Exact geometry requirement
44
device (Device): Device-wide constraint
45
startAlign (Alignment): Start alignment requirement
46
endAlign (Alignment): End alignment requirement
47
startRange (Geometry): Allowed start position range
48
endRange (Geometry): Allowed end position range
49
minSize (int): Minimum size in sectors
50
maxSize (int): Maximum size in sectors
51
52
Raises:
53
ConstraintException: If parameters are invalid or incompatible
54
"""
55
```
56
57
### Constraint Operations
58
59
Methods for combining and manipulating constraints.
60
61
```python { .api }
62
class Constraint:
63
def intersect(constraint: Constraint) -> Constraint:
64
"""
65
Create constraint representing intersection of two constraints.
66
New constraint satisfies both original constraints.
67
68
Args:
69
constraint (Constraint): Constraint to intersect with
70
71
Returns:
72
Constraint: Intersection constraint
73
74
Raises:
75
CreateException: If intersection cannot be created
76
ArithmeticError: If calculation fails
77
"""
78
79
def duplicate() -> Constraint:
80
"""
81
Create a copy of this constraint.
82
83
Returns:
84
Constraint: Duplicated constraint object
85
86
Raises:
87
CreateException: If duplication fails
88
"""
89
```
90
91
### Constraint Solving
92
93
Methods for finding geometries that satisfy constraint requirements.
94
95
```python { .api }
96
class Constraint:
97
def solveMax(geometry: Geometry) -> Geometry:
98
"""
99
Find largest geometry satisfying constraint near given geometry.
100
101
Args:
102
geometry (Geometry): Reference geometry for solving
103
104
Returns:
105
Geometry: Maximum geometry satisfying constraint
106
107
Raises:
108
ArithmeticError: If no solution exists
109
"""
110
111
def solveNearest(geometry: Geometry) -> Geometry:
112
"""
113
Find geometry satisfying constraint nearest to given geometry.
114
115
Args:
116
geometry (Geometry): Reference geometry for solving
117
118
Returns:
119
Geometry: Nearest geometry satisfying constraint
120
121
Raises:
122
ArithmeticError: If no solution exists
123
"""
124
125
def isSolution(geometry: Geometry) -> bool:
126
"""
127
Check if geometry satisfies this constraint.
128
129
Args:
130
geometry (Geometry): Geometry to test
131
132
Returns:
133
bool: True if geometry satisfies constraint
134
"""
135
```
136
137
## Device Constraint Methods
138
139
Device objects provide convenient methods for creating common constraint types.
140
141
```python { .api }
142
class Device:
143
def getConstraint() -> Constraint:
144
"""
145
Get constraint that accepts any region on device.
146
147
Returns:
148
Constraint: Device-wide constraint
149
"""
150
151
def getMinimalAlignedConstraint() -> Constraint:
152
"""
153
Get constraint with minimal alignment requirements.
154
155
Returns:
156
Constraint: Minimal alignment constraint
157
"""
158
159
def getOptimalAlignedConstraint() -> Constraint:
160
"""
161
Get constraint with optimal alignment for performance.
162
163
Returns:
164
Constraint: Optimal alignment constraint
165
"""
166
```
167
168
## Usage Examples
169
170
### Basic Constraint Creation
171
172
```python
173
import parted
174
175
device = parted.getDevice('/dev/sda')
176
177
# Create device-wide constraint (accepts any region)
178
device_constraint = device.getConstraint()
179
180
# Create optimal alignment constraint
181
optimal_constraint = device.getOptimalAlignedConstraint()
182
183
# Create minimal alignment constraint
184
minimal_constraint = device.getMinimalAlignedConstraint()
185
186
print("Constraints created for device operations")
187
```
188
189
### Custom Constraint Creation
190
191
```python
192
import parted
193
194
device = parted.getDevice('/dev/sdb')
195
196
# Get alignment requirements
197
start_alignment = device.getOptimumAlignment()
198
end_alignment = device.getOptimumAlignment()
199
200
# Define allowed ranges
201
device_geometry = parted.Geometry(device, start=0, length=device.length)
202
start_range = parted.Geometry(device, start=2048, length=device.length - 2048)
203
end_range = device_geometry
204
205
# Define size constraints (1GB to 100GB)
206
min_size = (1 * 1024**3) // device.sectorSize
207
max_size = (100 * 1024**3) // device.sectorSize
208
209
# Create custom constraint
210
custom_constraint = parted.Constraint(
211
startAlign=start_alignment,
212
endAlign=end_alignment,
213
startRange=start_range,
214
endRange=end_range,
215
minSize=min_size,
216
maxSize=max_size
217
)
218
219
print(f"Custom constraint: min={min_size}, max={max_size} sectors")
220
```
221
222
### Constraint Intersection
223
224
```python
225
import parted
226
227
device = parted.getDevice('/dev/sda')
228
229
# Create different constraints
230
size_constraint = parted.Constraint(
231
startAlign=device.getMinimumAlignment(),
232
endAlign=device.getMinimumAlignment(),
233
startRange=parted.Geometry(device, start=0, length=device.length),
234
endRange=parted.Geometry(device, start=0, length=device.length),
235
minSize=1000000, # ~500MB
236
maxSize=2000000 # ~1GB
237
)
238
239
alignment_constraint = device.getOptimalAlignedConstraint()
240
241
# Intersect constraints to get one that satisfies both
242
combined_constraint = size_constraint.intersect(alignment_constraint)
243
244
print("Combined constraint created with size and alignment requirements")
245
```
246
247
### Constraint Solving
248
249
```python
250
import parted
251
252
device = parted.getDevice('/dev/sdb')
253
disk = parted.newDisk(device)
254
255
# Create constraint for new partition
256
constraint = device.getOptimalAlignedConstraint()
257
258
# Define desired geometry (10GB starting at sector 2048)
259
desired_start = 2048
260
desired_size = (10 * 1024**3) // device.sectorSize
261
desired_geometry = parted.Geometry(device, start=desired_start, length=desired_size)
262
263
# Check if desired geometry satisfies constraint
264
if constraint.isSolution(desired_geometry):
265
print("Desired geometry satisfies constraint")
266
final_geometry = desired_geometry
267
else:
268
print("Adjusting geometry to satisfy constraint")
269
270
# Find nearest geometry that satisfies constraint
271
final_geometry = constraint.solveNearest(desired_geometry)
272
273
# Or find maximum geometry that satisfies constraint
274
# final_geometry = constraint.solveMax(desired_geometry)
275
276
print(f"Final geometry: start={final_geometry.start}, length={final_geometry.length}")
277
278
# Create partition with solved geometry
279
partition = parted.Partition(
280
disk=disk,
281
type=parted.PARTITION_NORMAL,
282
geometry=final_geometry
283
)
284
285
disk.addPartition(partition, constraint)
286
disk.commit()
287
```
288
289
### Constraint-Based Partition Resizing
290
291
```python
292
import parted
293
294
device = parted.getDevice('/dev/sdc')
295
disk = parted.newDisk(device)
296
partition = disk.getPartitionByNumber(1)
297
298
if partition and not partition.isBusy():
299
# Create constraint for resizing
300
constraint = device.getOptimalAlignedConstraint()
301
302
# Try to maximize partition
303
try:
304
max_geometry = constraint.solveMax(partition.geometry)
305
print(f"Maximum possible size: {max_geometry.length} sectors")
306
307
# Apply maximum geometry
308
disk.setPartitionGeometry(
309
partition,
310
constraint,
311
max_geometry.start,
312
max_geometry.end
313
)
314
315
disk.commit()
316
print("Partition maximized successfully")
317
318
except ArithmeticError:
319
print("Cannot find larger geometry satisfying constraints")
320
```
321
322
### Complex Constraint Scenarios
323
324
```python
325
import parted
326
327
device = parted.getDevice('/dev/sda')
328
329
# Create constraint for system partition (small, at beginning)
330
system_geometry = parted.Geometry(device, start=2048, length=1048576) # ~512MB
331
system_constraint = parted.Constraint(exactGeom=system_geometry)
332
333
# Create constraint for data partition (rest of disk, optimally aligned)
334
data_start = 2048 + 1048576
335
data_length = device.length - data_start - 1024 # Leave space at end
336
data_range = parted.Geometry(device, start=data_start, length=data_length)
337
338
data_constraint = parted.Constraint(
339
startAlign=device.getOptimumAlignment(),
340
endAlign=device.getOptimumAlignment(),
341
startRange=data_range,
342
endRange=data_range,
343
minSize=data_length // 2, # At least half the available space
344
maxSize=data_length
345
)
346
347
print("Created constraints for system and data partitions")
348
349
# Test if constraints can be satisfied
350
test_system_geom = parted.Geometry(device, start=2048, length=1048576)
351
test_data_geom = parted.Geometry(device, start=data_start, length=data_length)
352
353
system_ok = system_constraint.isSolution(test_system_geom)
354
data_ok = data_constraint.isSolution(test_data_geom)
355
356
print(f"System constraint satisfied: {system_ok}")
357
print(f"Data constraint satisfied: {data_ok}")
358
```
359
360
### Constraint Debugging
361
362
```python
363
import parted
364
365
device = parted.getDevice('/dev/sda')
366
constraint = device.getOptimalAlignedConstraint()
367
368
# Create test geometry
369
test_geometry = parted.Geometry(device, start=1000, length=2000000)
370
371
if not constraint.isSolution(test_geometry):
372
print("Geometry doesn't satisfy constraint")
373
374
# Try to find what would work
375
try:
376
nearest = constraint.solveNearest(test_geometry)
377
max_geom = constraint.solveMax(test_geometry)
378
379
print(f"Original: start={test_geometry.start}, length={test_geometry.length}")
380
print(f"Nearest: start={nearest.start}, length={nearest.length}")
381
print(f"Maximum: start={max_geom.start}, length={max_geom.length}")
382
383
except ArithmeticError as e:
384
print(f"No solution found: {e}")
385
else:
386
print("Geometry satisfies constraint")
387
```
388
389
## Constraint Types
390
391
### Geometry-Based Constraints
392
- **Exact Geometry**: Partition must use specific geometry
393
- **Min/Max Geometry**: Partition must fit within bounds
394
- **Device Constraint**: Any region on device is acceptable
395
396
### Alignment Constraints
397
- **Start Alignment**: Start sector must be aligned
398
- **End Alignment**: End sector must be aligned
399
- **Combined Alignment**: Both start and end aligned
400
401
### Size Constraints
402
- **Minimum Size**: Partition must be at least specified size
403
- **Maximum Size**: Partition cannot exceed specified size
404
- **Size Range**: Partition size must be within range
405
406
### Position Constraints
407
- **Start Range**: Start sector must be within range
408
- **End Range**: End sector must be within range
409
- **Region Constraint**: Entire partition within region
410
411
## Best Practices
412
413
1. **Always Use Constraints**: Never create partitions without constraints
414
2. **Combine Constraints**: Use intersection for multiple requirements
415
3. **Check Solutions**: Verify geometries satisfy constraints before use
416
4. **Handle Failures**: Be prepared for unsolvable constraint scenarios
417
5. **Use Device Constraints**: Leverage device-provided constraints for safety