Skip to content

Commit

Permalink
Merge pull request #137 from adrianchiris/allow-dot-in-kind
Browse files Browse the repository at this point in the history
Support dots in Kind name segment
  • Loading branch information
bart0sh authored May 8, 2023
2 parents b5ab017 + 19856fb commit 27b6bc1
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 41 deletions.
1 change: 1 addition & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Released versions of the spec are available as Git tags.
| v0.4.0 | | Added `type` field to Mount specification |
| v0.5.0 | | Add `HostPath` to `DeviceNodes` |
| v0.6.0 | | Add `Annotations` field to `Spec` and `Device` specifications |
| | | Allow dots (`.`) in name segment of `Kind` field |

*Note*: The initial release of a **spec** with version `v0.x.0` will be tagged as
`v0.x.0` with subsequent changes to the API applicable to this version tagged as `v0.x.y`.
Expand Down
8 changes: 2 additions & 6 deletions pkg/cdi/qualified-device.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@ import (
//
// "<vendor>/<class>=<name>".
//
// A valid vendor name may contain the following runes:
// A valid vendor and class name may contain the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
//
// A valid class name may contain the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_'.
//
// A valid device name may containe the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
Expand Down Expand Up @@ -98,7 +94,7 @@ func ValidateVendorName(vendor string) error {
// A class name may contain the following ASCII characters:
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
// - digits ('0'-'9')
// - underscore and dash ('_', '-')
// - underscore, dash, and dot ('_', '-', and '.')
//
// Deprecated: use parser.ValidateClassName instead
func ValidateClassName(class string) error {
Expand Down
7 changes: 7 additions & 0 deletions pkg/cdi/qualified-device_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ func TestQualifiedName(t *testing.T) {
name: "dev1",
isQualified: true,
},
{
device: "vendor1.com/class.subclass=dev1",
vendor: "vendor1.com",
class: "class.subclass",
name: "dev1",
isQualified: true,
},
{
device: "other-vendor1.com/class_1=dev_1",
vendor: "other-vendor1.com",
Expand Down
7 changes: 7 additions & 0 deletions pkg/cdi/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,13 @@ func TestRequiredVersion(t *testing.T) {
},
expectedVersion: "0.6.0",
},
{
description: "dotted name (class) label require v0.6.0",
spec: &cdi.Spec{
Kind: "vendor.com/class.sub",
},
expectedVersion: "0.6.0",
},
}

for _, tc := range testCases {
Expand Down
8 changes: 8 additions & 0 deletions pkg/cdi/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ func requiresV060(spec *cdi.Spec) bool {
}
}

// The v0.6.0 spec allows dots "." in Kind name label (class)
vendor, class := parser.ParseQualifier(spec.Kind)
if vendor != "" {
if strings.ContainsRune(class, '.') {
return true
}
}

return false
}

Expand Down
65 changes: 30 additions & 35 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,10 @@ import (
//
// "<vendor>/<class>=<name>".
//
// A valid vendor name may contain the following runes:
// A valid vendor and class name may contain the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
//
// A valid class name may contain the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_'.
//
// A valid device name may containe the following runes:
//
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
Expand Down Expand Up @@ -122,52 +118,51 @@ func ParseQualifier(kind string) (string, string) {
// - digits ('0'-'9')
// - underscore, dash, and dot ('_', '-', and '.')
func ValidateVendorName(vendor string) error {
if vendor == "" {
return fmt.Errorf("invalid (empty) vendor name")
}
if !IsLetter(rune(vendor[0])) {
return fmt.Errorf("invalid vendor %q, should start with letter", vendor)
}
for _, c := range string(vendor[1 : len(vendor)-1]) {
switch {
case IsAlphaNumeric(c):
case c == '_' || c == '-' || c == '.':
default:
return fmt.Errorf("invalid character '%c' in vendor name %q",
c, vendor)
}
}
if !IsAlphaNumeric(rune(vendor[len(vendor)-1])) {
return fmt.Errorf("invalid vendor %q, should end with a letter or digit", vendor)
err := validateVendorOrClassName(vendor)
if err != nil {
err = fmt.Errorf("invalid vendor. %w", err)
}

return nil
return err
}

// ValidateClassName checks the validity of class name.
// A class name may contain the following ASCII characters:
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
// - digits ('0'-'9')
// - underscore and dash ('_', '-')
// - underscore, dash, and dot ('_', '-', and '.')
func ValidateClassName(class string) error {
if class == "" {
return fmt.Errorf("invalid (empty) device class")
err := validateVendorOrClassName(class)
if err != nil {
err = fmt.Errorf("invalid class. %w", err)
}
if !IsLetter(rune(class[0])) {
return fmt.Errorf("invalid class %q, should start with letter", class)
return err
}

// validateVendorOrClassName checks the validity of vendor or class name.
// A name may contain the following ASCII characters:
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
// - digits ('0'-'9')
// - underscore, dash, and dot ('_', '-', and '.')
func validateVendorOrClassName(name string) error {
if name == "" {
return fmt.Errorf("empty name")
}
for _, c := range string(class[1 : len(class)-1]) {
if !IsLetter(rune(name[0])) {
return fmt.Errorf("%q, should start with letter", name)
}
for _, c := range string(name[1 : len(name)-1]) {
switch {
case IsAlphaNumeric(c):
case c == '_' || c == '-':
case c == '_' || c == '-' || c == '.':
default:
return fmt.Errorf("invalid character '%c' in device class %q",
c, class)
return fmt.Errorf("invalid character '%c' in name %q",
c, name)
}
}
if !IsAlphaNumeric(rune(class[len(class)-1])) {
return fmt.Errorf("invalid class %q, should end with a letter or digit", class)
if !IsAlphaNumeric(rune(name[len(name)-1])) {
return fmt.Errorf("%q, should end with a letter or digit", name)
}

return nil
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ func TestQualifiedName(t *testing.T) {
name: "dev1",
isQualified: true,
},
{
device: "vendor1.com/class.subclass=dev1",
vendor: "vendor1.com",
class: "class.subclass",
name: "dev1",
isQualified: true,
},
{
device: "other-vendor1.com/class_1=dev_1",
vendor: "other-vendor1.com",
Expand Down

0 comments on commit 27b6bc1

Please sign in to comment.