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

dnn-fn #70

Merged
merged 7 commits into from
May 12, 2023
Merged

dnn-fn #70

merged 7 commits into from
May 12, 2023

Conversation

henderiw
Copy link
Contributor

DNN-fn operates on DNN resource and can request IP Allocations.

@henderiw henderiw added this to the sprint1 milestone Mar 30, 2023
@henderiw henderiw linked an issue Mar 30, 2023 that may be closed by this pull request
3 tasks
@henderiw henderiw added the area/package-specialization SIG Automation Package Specialization Subproject label Mar 30, 2023
@gvbalaji gvbalaji modified the milestones: sprint1, sprint2 Apr 11, 2023
@nephio-prow nephio-prow bot added the approved label Apr 19, 2023
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Apr 19, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

Watch: map[corev1.ObjectReference]kptcondsdk.WatchCallbackFn{
{
APIVersion: infrav1alpha1.GroupVersion.Identifier(),
Kind: "ClusterContext",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: Instead of embeded "ClusterContext" string you can use..

Kind: reflect.TypeOf(infrav1alpha1.ClusterContext{}).Name(),

Copy link
Contributor

Choose a reason for hiding this comment

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

you are absolutely right. the string literal was meant to be temporary, I just forgot to put a TODO next to it :)
Since ClusterContext is a proper kubebuilder-style K8s API object I am planning to use the usual "Scheme" method to get the name of it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

@@ -17,11 +17,218 @@ limitations under the License.
package parser
Copy link
Contributor

Choose a reason for hiding this comment

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

All the lib files are already part of seperate PR, these needs to be removed from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

that's actually a very good topic. What I did is that I merged that PR's branch into mine, and this is how the files from the sdk PR ended up in my branch.
I thought this is the way to base your PR to another one. Do we have a better method on basing PR on other PRs? Was it already discussed, or is it written somewhere?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

@@ -21,12 +21,7 @@ import (

Copy link
Contributor

Choose a reason for hiding this comment

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

All the lib files are already part of seperate PR, these needs to be removed from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

@@ -0,0 +1,436 @@
package v1alpha1
Copy link
Contributor

Choose a reason for hiding this comment

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

All the lib files are already part of seperate PR, these needs to be removed from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

@@ -0,0 +1,180 @@
# Conditional kpt fn sdk
Copy link
Contributor

Choose a reason for hiding this comment

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

All the lib files are already part of seperate PR, these needs to be removed from this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

},
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"nephio.org/site": f.site,
Copy link
Contributor

Choose a reason for hiding this comment

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

req to use SiteAnnotationKey instead of embeded string

Copy link
Contributor

Choose a reason for hiding this comment

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

oops, you are right of course :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

if err != nil {
return err
}
f.site = *cluster.Spec.SiteCode
Copy link
Contributor

Choose a reason for hiding this comment

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

Here if the siteCode field is not available on clustercontext yaml then following occurs:
panic: runtime error: invalid memory address or nil pointer dereference

it would be better to handle it here..

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 3395624

Copy link
Contributor Author

@henderiw henderiw left a comment

Choose a reason for hiding this comment

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

why are we using the runtime scheme if we can access the schema direct. Avoiding it removes some code


// var _ fn.Runner = &DnnFn{}

var theScheme *runtime.Scheme = runtime.NewScheme()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

why do we add this here? we can access the schema direct w/o going to runtime scheme. avoids some code

Copy link
Contributor

Choose a reason for hiding this comment

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

you are right, of course. in this case using runtime is way too complicated to obtain the Kind of a go type.

These helper functions are just experimental code that I hoped can be the basis for future convenience methods (like FilterByType in lib.go). I am happy to remove it, if it is confusing, or we can keep it, so that it inspires others to create other convenient generic helper functions.


// GetKindOrPanic returns with the Kind of a Kubernetes API resource type `T`.
// Panics if `T` is not registered in the `theScheme`
func GetKindOrPanic[T any, PT interface {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

can be avoided if we don't go to the scheme

if found {
pools = append(pools, DnnPoolStatus{Name: poolName, Ip: ipalloc.Status})
} else {
f.rl.Results.Warningf("found an owned IPAllocation with a suspicious name: %v", ipalloc.Name)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is it not better to log rather than adding to resourceList? I would like to avoid adding to resourceList.

@henderiw
Copy link
Contributor Author

Need to discuss the test strategy if adding all these files is a good approach or not

@kispaljr
Copy link
Contributor

why are we using the runtime scheme if we can access the schema direct. Avoiding it removes some code

you are right, of course. in this case using runtime is way too complicated to obtain the Kind of a go type.

These helper functions are just experimental code that I hoped can be the basis for future convenience methods (like FilterByType in lib.go). I am happy to remove it, if it is confusing, or we can keep it, so that it inspires others to create other convenient generic helper functions.

@kispaljr
Copy link
Contributor

Need to discuss the test strategy if adding all these files is a good approach or not

Based on our discussion yesterday I've created a PR for moving my test helper functions into lib/: #134

@henderiw
Copy link
Contributor Author

@kispaljr can you look at the build issues ?

@gvbalaji
Copy link

gvbalaji commented May 5, 2023

Thanks @henderiw . A rebase needed for this PR.

@kispaljr
Copy link
Contributor

kispaljr commented May 8, 2023

Tests will pass only after #170 is merged


var theScheme *runtime.Scheme = runtime.NewScheme()

func init() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you still need the schema stuff?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't use it to get the Kind of ClusterContext and others, but I use it in functions like FilterByType[IPAllocation], where I think it's quite elegant (however I admit that it is subjective)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is an example how I did it in the interface-fn. You basically know the types based on GVK as it is 1:1 mapping

ipallocs := objs.Where(fn.IsGroupVersionKind(ipamv1alpha1.IPAllocationGroupVersionKind))
for _, ipalloc := range ipallocs {
if ipalloc.GetName() == forObj.GetName() {
alloc, err := kubeobject.NewFromKubeObjectipamv1alpha1.IPAllocation
if err != nil {
return nil, err
}
allocGoStruct, err := alloc.GetGoStruct()
if err != nil {
return nil, err
}
itfce.Status.IPAllocationStatus = &allocGoStruct.Status
}
}

Copy link
Contributor

@kispaljr kispaljr May 10, 2023

Choose a reason for hiding this comment

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

Yes, exactly. FilterByType[IPAllocation] implements the exact same functionality as the first 12 lines of your code. Since this code is copy-pasted into all of our KRM functions, I thought it is a prime candidate to be factored out into a utility function.
Does this cause a problem?

Copy link
Contributor

Choose a reason for hiding this comment

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

Btw with latest lib, the above doesn't work instead it has to be:
objs.Where(fn.IsGroupVersionKind(schema.GroupVersionKind(ipamv1alpha1.IPAllocationGroupVersionKind)))

@@ -0,0 +1 @@
_actual_output.yaml
Copy link

Choose a reason for hiding this comment

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

Should this file be ignored? Plus new line

Copy link
Contributor

Choose a reason for hiding this comment

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

newline added (will be pushed in a sec)
_actual_output.yaml files are a byproduct of running the tests, but they are not needed in the repo


FROM gcr.io/distroless/static:latest
COPY --from=0 /usr/local/bin/function /usr/local/bin/function
ENTRYPOINT ["function"]
Copy link

Choose a reason for hiding this comment

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

New line

matchLabels:
nephio.org/site: edge1
networkInstance: {}
prefixLength: 8
Copy link

Choose a reason for hiding this comment

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

newline

Copy link
Contributor

Choose a reason for hiding this comment

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

fixing it
we should consider adding a presubmit test that automatically checks newline-at-the-end-of-file :)

@gvbalaji gvbalaji modified the milestones: sprint3, sprint4 May 9, 2023
myFn := DnnFn{rl: rl}

// get ClusterContext
myFn.ClusterContext, err = GetSingleton[infrav1alpha1.ClusterContext](rl.Items)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we want to avoid doing this. We should use the watch to handle this. The watch adds functionality you will not get if we use it this way.

Copy link
Contributor

Choose a reason for hiding this comment

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

This was meant to be a temporary solution until the singleton functionality we talked about will be part of the SDK. Is it already available? I will update this to the SDK if it is available.

Copy link
Contributor

Choose a reason for hiding this comment

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

I looked, and didn't find, so I am reverting back to the old Watch callback-based version

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can add singleton to the sdk. it would be better to have it there

Copy link
Contributor

@kispaljr kispaljr May 10, 2023

Choose a reason for hiding this comment

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

reverted back from calling the GetSingleton[ClusterContext]() utility function to manually checking in ClusterContextCallback and PopulateFnCallback the validity of ClusterContexts


var theScheme *runtime.Scheme = runtime.NewScheme()

func init() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is an example how I did it in the interface-fn. You basically know the types based on GVK as it is 1:1 mapping

ipallocs := objs.Where(fn.IsGroupVersionKind(ipamv1alpha1.IPAllocationGroupVersionKind))
for _, ipalloc := range ipallocs {
if ipalloc.GetName() == forObj.GetName() {
alloc, err := kubeobject.NewFromKubeObjectipamv1alpha1.IPAllocation
if err != nil {
return nil, err
}
allocGoStruct, err := alloc.GetGoStruct()
if err != nil {
return nil, err
}
itfce.Status.IPAllocationStatus = &allocGoStruct.Status
}
}

@kispaljr
Copy link
Contributor

kispaljr commented May 10, 2023

GitHub working strange to me, somehow I have trouble replying to this, so I will just copy-paste:

Here is an example how I did it in the interface-fn. You basically know the types based on GVK as it is 1:1 mapping

ipallocs := objs.Where(fn.IsGroupVersionKind(ipamv1alpha1.IPAllocationGroupVersionKind))
for _, ipalloc := range ipallocs {
if ipalloc.GetName() == forObj.GetName() {
alloc, err := kubeobject.NewFromKubeObject[ipamv1alpha1.IPAllocation](https://github.com/nephio-project/nephio/pull/ipalloc)
if err != nil {
return nil, err
}
allocGoStruct, err := alloc.GetGoStruct()
if err != nil {
return nil, err
}
itfce.Status.IPAllocationStatus = &allocGoStruct.Status
}
}

Yes, exactly. FilterByType[IPAllocation] implements the exact same functionality as the first 12 lines of your code. Since this code is copy-pasted into all of our KRM functions, I thought it is a prime candidate to be factored out into a utility function.
Does this cause a problem?

@kispaljr
Copy link
Contributor

/retest

@kispaljr kispaljr requested a review from aakashchan May 12, 2023 11:15

<!--mdtogo:Long-->

## Usage
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a suggestion, for the sake of alignment what do you think about changing the content of usage sub-section?

https://github.com/nephio-project/nephio/tree/main/krm-functions/interface-fn#usage
https://github.com/nephio-project/nephio/blob/main/krm-functions/ipam-fn/README.md
https://github.com/nephio-project/nephio/blob/main/krm-functions/nad-fn/README.md#usage

This section can be named as Implementation details, perhaps?

@henderiw
Copy link
Contributor Author

/approve

@nephio-prow
Copy link
Contributor

nephio-prow bot commented May 12, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: henderiw

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@nephio-prow nephio-prow bot added the approved label May 12, 2023
@ganchandrasekaran
Copy link
Contributor

/lgtm

@nephio-prow nephio-prow bot added the lgtm label May 12, 2023
@nephio-prow nephio-prow bot merged commit a81cdef into nephio-project:main May 12, 2023
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved area/package-specialization SIG Automation Package Specialization Subproject lgtm
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Develop DNN for package specialization
4 participants