Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Annotations to CDI Spec #85

Merged
merged 5 commits into from
Mar 14, 2023
Merged

Conversation

zvonkok
Copy link
Contributor

@zvonkok zvonkok commented Oct 19, 2022

Based on the discussion in #30 some generated devices like VFs need extra meta information to be handled correctly in virtualized environments.

@zvonkok
Copy link
Contributor Author

zvonkok commented Oct 19, 2022

For Kata we need to pass through the VF into the container, a VF can have different types and with the BDF the runtime can deduce the right handling. An example CDI spec would look like:

# /etc/cdi/nvidia.yaml
cdiVersion: 0.4.0
kind: nvidia.com/gpu
devices:
- name: gpu0
  annotations:
    bdf: “41:00.0”
    clique-id: “0”
  containerEdits:
    deviceNodes:
    - path: “/dev/vfio/71"

elezar
elezar previously requested changes Oct 20, 2022
Copy link
Contributor

@elezar elezar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @zvonkok. Could you also provide a short description on how these will be used.

Some other points:

  • This requires a version bump of the spec. Let us do that now.
  • Could we add an example to the readme etc. where this is specified?

specs-go/config.go Show resolved Hide resolved
@zvonkok
Copy link
Contributor Author

zvonkok commented Nov 2, 2022

Refactored the README according to md-lint suggestions.

Copy link
Contributor

@kad kad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beside clarification on usage of annotation field, it is ok from my side.

One side note noticed during this PR review, probably good for another PR: I've noticed that in our schema doesn't specify "global" containerEdits fields in schema/schema.json

specs-go/config.go Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
@zvonkok
Copy link
Contributor Author

zvonkok commented Nov 3, 2022

@kad @klihub @elezar I added validation of annotations PTAL; I have a general question why are we allowing an empty CDI spec to be valid? What is the purpose?
For validating annotations, I am at least assuming to have Kind and some other fields to be set.

# /etc/cdi/nvidia.yaml
cdiVersion: 0.4.0
kind: nvidia.com/gpu
annotations: 
  global: "true"
devices:
- name: gpu0
  annotations:
    bdf: “41:00.0”
    badfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasfasdfasfsddf: “41:00.0”
    clique-id: “0”
  containerEdits:
    deviceNodes:
    - path: “/dev/vfio/71"
# bin/validate /tmp/nvidia.yaml
Building bin/validate...
Validating against JSON schema builtin...
/tmp/nvidia.yaml: validation failed:
    [[]: Invalid value: "badfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasfasdfasfsddf": name part must be no more than 63 characters]

specs-go/config.go Outdated Show resolved Hide resolved
Copy link
Contributor

@elezar elezar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the validation @zvonkok. Some comments -- specifically about when this validation is triggered.

schema/schema.go Outdated Show resolved Hide resolved
schema/schema.go Outdated Show resolved Hide resolved
schema/schema.go Outdated Show resolved Hide resolved
schema/schema_test.go Outdated Show resolved Hide resolved
specs-go/config.go Outdated Show resolved Hide resolved
@zvonkok zvonkok force-pushed the annotations branch 4 times, most recently from 6b78d1c to 5080b88 Compare November 17, 2022 09:49
@klihub
Copy link
Contributor

klihub commented Nov 17, 2022

I have a general question why are we allowing an empty CDI spec to be valid? What is the purpose?

AFAICT, it is partly for historical reasons. IIRC how it came to be, Renaud's initial code was explicitly allowing for it, so we kept that functionality. My guess is that the orignal idea was to let vendor-specific utilities run at boot-time and generate vendor-specific 'static' Spec files in /etc (maybe by scanning /dev, and/or doing udev enumeration) and allow any empty files to indicate that the utilities did run (maybe using comments to that effect in the generated Spec files) but not trigger errors in the actual cdi Spec-handling packages. But I'm just guessing here...

Copy link
Contributor

@elezar elezar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zvonkok I have reworked this PR so that it can be merged into the current main branch. This includes checks for the minimum version, for example.

I have also reworked the annotation validation to reduce the imported k8s dependencies.

@klihub @bart0sh @kad since I've also updated this PR please take a look now.

@elezar elezar requested review from elezar and removed request for elezar February 9, 2023 15:22
@elezar elezar dismissed their stale review February 9, 2023 15:24

I updated the branch myself.

@elezar elezar requested a review from klihub February 10, 2023 12:54
@klihub klihub requested review from bart0sh and kad February 14, 2023 13:17
@bart0sh
Copy link
Contributor

bart0sh commented Feb 15, 2023

It would be nice to cover new code with unit tests.
Other than that lgtm.

@klihub
Copy link
Contributor

klihub commented Feb 20, 2023

This needs a rebase and conflict resolution. Other than that, I think it looks fine.

elezar and others added 4 commits February 20, 2023 10:41
Signed-off-by: Evan Lezar <elezar@nvidia.com>
This change adds an internal validation package for spec annotation validation.
This includes code imported from k8s.io/apimachinery/pkg/api and k8s.io/apimachinery/pkg/util
to allow for basic validation of the annotations without importing additional
dependencies.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This change allows a set of annotations to be specified at a
spec level as well as per device defined in the spec.

This bumps the spec version to 0.6.0.

Note that validation of the contents of the annotations is also
included at a schema level.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
@elezar
Copy link
Contributor

elezar commented Feb 20, 2023

This needs a rebase and conflict resolution. Other than that, I think it looks fine.

Done.

)

// ValidateSpecAnnotations checks whether spec annotations are valid.
func ValidateSpecAnnotations(name string, any interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klihub I believe you had questions / concerns about the validation of the annotations.

)

// ValidateSpecAnnotations checks whether spec annotations are valid.
func ValidateSpecAnnotations(name string, any interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for not having the map[string]string type for annotations as in the Spec itself ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is called from the schema validation, where all we have is an interface{} type. This handles the conversion of this type to a map[string]string. Since this is required for two separate parts of the schema / spec (top-level annotations and device-level annotation), I added this helper here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I can rename this helper to ValidateSpecAnnotationSchema instead.

Antother option is to drop the schema validation entirely which would clean up this PR significantly.

Copy link
Contributor

@klihub klihub Feb 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is sort of tempting... Then again, if at all possible it is better to catch Spec errors early (when seen first time by the CDI package) than late (when an injection goes wrong in the runtime). So I guess then some basic annotation verification would be a good idea.

That said, I don't know if these checks are really that helpful in that regard. AFAICT we don't plan to inject any of these annotations to a container and we are doing K8s pod/container annotations verification here. If we don't inject them, some entity somewhere along the runtime-runc/crun/kata path will do some semantic interpretation of the annotated data... which inevitable leaves the door open for delayed post-injection errors.

@zvonkok
Copy link
Contributor Author

zvonkok commented Mar 13, 2023

@kad @klihub @bart0sh Anything missing to merge this?

@klihub
Copy link
Contributor

klihub commented Mar 13, 2023

@zvonkok Not from my point of view. As I stated in my last review comment I'm fine with merging this as such, or if @elezar wants to drop ValidateSpecAnnotations, I'm also fine with that.

@elezar
Copy link
Contributor

elezar commented Mar 13, 2023

@zvonkok Not from my point of view. As I stated in my last review comment I'm fine with merging this as such, or if @elezar wants to drop ValidateSpecAnnotations, I'm also fine with that.

Since we don't validate by default, I think we can leave it in for the time being. If you're good with it @klihub let's get this merged and I we can bump a new version.

// The v0.6.0 spec allows annotations to be specified at a device level
for _, d := range spec.Devices {
for range d.Annotations {
return true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a loop here if we unconditionally return on the first iteration?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent of the loop is to detect whether a v0.6.0 spec is required. This is required if ANY annotions are detected.

We could use:

	for _, d := range spec.Devices {
   		if len(d.Annotations) > 0 {
			return true

instead, but I thought the loop was cleaner than the conditional in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for me, but I'm ok with it.

Copy link
Contributor

@klihub klihub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@bart0sh bart0sh merged commit 9c1a1bd into cncf-tags:main Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants