Today
Every TargetDiskHints field is an exact comparison (internal/diskmatch/diskmatch.go's hintsMatch):
deviceName, serialNumber, wwn, pciePath, hctl compare byte-for-byte.
model and vendor compare after trimming whitespace.
minSizeGigabytes, maxSizeGigabytes, rotational, slotNumber compare numerically.
Set fields are ANDed; unset fields do not constrain. Match then requires exactly one disk to satisfy the hints - zero and 2+ are both errors.
The only non-exact selection available today is a size range plus rotational, e.g. "the one SSD of 200 GiB or more".
The gap
Two hints are naturally patterned, and both are awkward to write exactly:
deviceName. A fleet where the target is "the first NVMe namespace" needs /dev/nvme0n1 spelled out per machine, even though /dev/nvme*n1 is the real intent. Writing a hint per machine is exactly what the field is meant to avoid.
model. Firmware model strings carry revision suffixes and padding that vary within one purchase batch (SAMSUNG MZQL2960HCJR-00A07 vs -00B07), so a hint that is right for one machine misses its neighbour.
Proposal
Add glob support for those two hints, as new, separate fields rather than changing what the existing ones mean:
targetDisk:
deviceNamePattern: "/dev/nvme*n1"
modelPattern: "SAMSUNG MZQL2960HCJR-*"
- Matching uses Go's
path.Match semantics (*, ?, [...]), case-sensitive, consistent with the exact fields.
- A pattern field ANDs with every other set hint, the same as any exact field.
modelPattern trims whitespace on the disk side before matching, matching model's existing behaviour.
- The "exactly one disk" rule does not change. A pattern that matches several disks is the same error an over-broad exact hint already produces, with the same "refine them" message listing the matching devices. A glob is a way to write one hint for a fleet, not a way to select a set.
- Setting both
deviceName and deviceNamePattern (or model and modelPattern) is rejected by the webhook rather than silently ANDed - two spellings of one constraint in one object is a configuration mistake.
Why glob, not regex
The pattern comes from a user-writable CR and is evaluated in the controller on every resolve. path.Match has no catastrophic-backtracking class of input, so it needs no complexity or length budget of its own. Regex would need one, and would buy expressiveness nothing in the cases above wants. If a real case later needs alternation or anchoring that glob cannot express, that is the point to revisit it - not before.
Scope
api/v1alpha1/machine_types.go: two fields on TargetDiskHints, plus hasAnyHint.
internal/diskmatch/diskmatch.go: the two hintsMatch arms, and unit tests for match, no-match, ambiguous-match, and a malformed pattern.
internal/webhook/v1alpha1/machine_webhook.go: reject a malformed pattern (path.Match returns ErrBadPattern) and reject the exact/pattern pair at admission, so a bad pattern fails at apply time rather than mid-deploy.
- CRD regeneration, and the hint documentation.
Machine.spec.targetDisk and every dataImages[].targetDisk share TargetDiskHints, so both get this at once.
Out of scope
serialNumber, wwn, pciePath, hctl, and vendor stay exact. A serial or WWN identifies one physical device, so a pattern over it has no meaning worth supporting; pciePath and hctl are structured addresses where a size or slot hint expresses the same intent more clearly.
Today
Every
TargetDiskHintsfield is an exact comparison (internal/diskmatch/diskmatch.go'shintsMatch):deviceName,serialNumber,wwn,pciePath,hctlcompare byte-for-byte.modelandvendorcompare after trimming whitespace.minSizeGigabytes,maxSizeGigabytes,rotational,slotNumbercompare numerically.Set fields are ANDed; unset fields do not constrain.
Matchthen requires exactly one disk to satisfy the hints - zero and 2+ are both errors.The only non-exact selection available today is a size range plus
rotational, e.g. "the one SSD of 200 GiB or more".The gap
Two hints are naturally patterned, and both are awkward to write exactly:
deviceName. A fleet where the target is "the first NVMe namespace" needs/dev/nvme0n1spelled out per machine, even though/dev/nvme*n1is the real intent. Writing a hint per machine is exactly what the field is meant to avoid.model. Firmware model strings carry revision suffixes and padding that vary within one purchase batch (SAMSUNG MZQL2960HCJR-00A07vs-00B07), so a hint that is right for one machine misses its neighbour.Proposal
Add glob support for those two hints, as new, separate fields rather than changing what the existing ones mean:
path.Matchsemantics (*,?,[...]), case-sensitive, consistent with the exact fields.modelPatterntrims whitespace on the disk side before matching, matchingmodel's existing behaviour.deviceNameanddeviceNamePattern(ormodelandmodelPattern) is rejected by the webhook rather than silently ANDed - two spellings of one constraint in one object is a configuration mistake.Why glob, not regex
The pattern comes from a user-writable CR and is evaluated in the controller on every resolve.
path.Matchhas no catastrophic-backtracking class of input, so it needs no complexity or length budget of its own. Regex would need one, and would buy expressiveness nothing in the cases above wants. If a real case later needs alternation or anchoring that glob cannot express, that is the point to revisit it - not before.Scope
api/v1alpha1/machine_types.go: two fields onTargetDiskHints, plushasAnyHint.internal/diskmatch/diskmatch.go: the twohintsMatcharms, and unit tests for match, no-match, ambiguous-match, and a malformed pattern.internal/webhook/v1alpha1/machine_webhook.go: reject a malformed pattern (path.MatchreturnsErrBadPattern) and reject the exact/pattern pair at admission, so a bad pattern fails at apply time rather than mid-deploy.Machine.spec.targetDiskand everydataImages[].targetDiskshareTargetDiskHints, so both get this at once.Out of scope
serialNumber,wwn,pciePath,hctl, andvendorstay exact. A serial or WWN identifies one physical device, so a pattern over it has no meaning worth supporting;pciePathandhctlare structured addresses where a size or slot hint expresses the same intent more clearly.